absi2011
一个新的开始吧w 希望这一次能如我所愿w

1001

大力猜结论

积出2*b,后面积不出来了

猜a*pi过掉了

罚时6次

大概就是

printf("%.6lf\n",2*b+a*pi-5e-7);

这样的代码

我讨厌这种题.....

 

1002

数学题

猜结论1:gcd(2x-1,2y-1)=2gcd(x,y)-1

猜结论2:gcd(F(x),F(y))=F(gcd(x,y))

然后容斥,求出答案

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int fact[20000005];
int anti_fact[20000005];
const int modo=1000000007;
int power(int x,int y)
{
    if (y==0) return 1;
    int t=power(x,y/2);
    t=(long long)t*t%modo;
    if (y%2==1)
    {
        t=(long long)t*x%modo;
    }
    return t;
}
int c(int n,int m)
{
    return (long long)fact[n]*anti_fact[m]%modo*anti_fact[n-m]%modo;
}
int f[1000005];
int ans[1000005];
int main()
{
    int i;
    fact[0]=1;
    for (i=1;i<=2000000;i++)
    {
        fact[i]=(long long)fact[i-1]*i%modo;
    }
    anti_fact[2000000]=power(fact[2000000],modo-2);
    for (i=2000000;i>=1;i--)
    {
        anti_fact[i-1]=(long long)anti_fact[i]*i%modo;
    }
    f[1]=1;
    for (i=2;i<=1000000;i++)
    {
        f[i]=f[i-1]+f[i-2];
        f[i]%=(modo-1);
    }
    int zu;
    int t;
    scanf("%d",&t);
    for (zu=0;zu<t;zu++)
    {
        int n,k;
        scanf("%d%d",&k,&n);
        int i;
        for (i=1;i<=k;i++)
        {
            if (k%i==0)
            {
                ans[i]=c(n+(k/i)-1,k/i);
            }
            else
            {
                ans[i]=0;
            }
        }
        for (i=k;i>=1;i--)
        {
            if (ans[i]!=0)
            {
                int j;
                for (j=i+i;j<=k;j+=i)
                {
                    ans[i]-=ans[j];
                    if (ans[i]<0) ans[i]+=modo;
                }
            }
        }
        int sum=0;
        for (i=1;i<=k;i++)
        {
            //printf("%d %d\n",i,ans[i]);
            if (ans[i]!=0)
            {
                sum=(sum+(long long)ans[i]*(power(2,f[i])-1))%modo;
            }
        }
        sum=(long long)sum*power(c(n+k-1,k),modo-2)%modo;
        printf("%d\n",sum);
    }
    return 0;
}

  

 

1009

村子里面可能全是狼,它们说的话是真是假无所谓

所以不可能有铁村民

接下来考虑铁狼,如果某个人是民一定会导致矛盾那么他就是狼

如果某个人是民,他说的一定是真话,那么如果他说别人是民,那个人肯定也说了真话

这样下去

我们可以得到一个链

这个链上的所有人都是民

如果链到一个已经访问过的人,他是铁狼,那么这一些人都是铁狼

如果链变成了环(互认为民),那么这些人一定不是铁狼,因为这个环可以成立

如果链到一个可以是民的人,那么看这个民链到最后指的狼是谁

如果没指(互认民的情况),那么就不是铁狼

如果指的到人,那么看这个人是否在环内

不在的话,就全可以是民,也就是不存在铁狼

如果存在的话,这个人是铁狼,所有认这个人是民的全部是铁狼

别的依旧是民

 

大概就讨论这么多了................

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define next s2i39
#define tpye d923l
char a[10005];
int next[1000005];
bool type[1000005];
int ans[100005];
bool vis[100005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int t;
    scanf("%d",&t);
    int zu;
    for (zu=0;zu<t;zu++)
    {
        int n;
        scanf("%d",&n);
        int i;
        for (i=0;i<n;i++)
        {
            int x;
            scanf("%d%s",&x,a);
            next[i]=x-1;
            if (a[0]=='w')
            {
                type[i]=1;
            }
            else
            {
                type[i]=0;
            }
            ans[i]=-1;
            vis[i]=false;
        }
        int sum=0;
        for (i=0;i<n;i++)
        {
            if (ans[i]!=-1)
            {
                continue;
            }
            if (type[i]==1)
            {
                sum++;
                ans[i]=1;
                continue;
            }
            int now;
            for (now=i;;now=next[now])
            {
                if (vis[now])
                {
                    break;
                }
                if (ans[now]==0)
                {
                    break;
                }
                if (type[now]==1)
                {
                    break;
                }
                vis[now]=true;
            }
            if (ans[now]==0)
            {
                int temp;
                for (temp=i;temp!=now;temp=next[temp])
                {
                    ans[temp]=0;
                }
            }
            else if (type[now]==0)
            {
                int temp;
                for (temp=i;ans[temp]!=1;temp=next[temp])
                {
                    ans[temp]=1;
                    sum++;
                }
            }
            else if (type[now]==1)
            {
                int temp;
                for (temp=i;temp!=now;temp=next[temp])
                {
                    if (temp==next[now])
                    {
                        break;
                    }
                }
                if (temp==now)
                {
                    //All OK
                    for (temp=i;temp!=now;)
                    {
                        ans[temp]=1;
                        sum++;
                        int ttemp=next[temp];
                        type[temp]=1;
                        next[temp]=next[now];
                        temp=ttemp;
                    }
                }
                else
                {
                    for (temp=next[temp];temp!=now;)
                    {
                        ans[temp]=1;
                        sum++;
                        int ttemp=next[temp];
                        type[temp]=1;
                        next[temp]=next[now];
                        temp=ttemp;
                    }
                    for (temp=i;temp!=now;temp=next[temp])
                    {
                        ans[temp]=0;
                        if (temp==next[now])
                        {
                            break;
                        }
                    }
                }
            }
        }
        printf("0 %d\n",n-sum);
    }
    return 0;
}

  

 

1011

又是个数学题......有点报警

讲道理别这么折磨我..让我写那么多数学题..........

首先题目里面的那个矩阵是

如果c(i,j) mod p = 0那么就是0,否则是1

那么先考虑n=1

那个矩阵的1次方,我们观察下

发现是长成这样的

1 0 .. 0

1 1 .. 0

..........

1 1 .. 1

这样的对角矩阵,那么我们k+1次方以后

我惊讶的发现,它是

C(k,k) 0 .. 0

C(k+1,k) C(k,k) .. 0

..................................

C(k+p-1,k) C(k+p-2,k) ..... C(k,k)

它们的和是

C(k+p+1,k+2)

也就是这个对角矩阵的k次方的和是

C(k+p,k+1)

那么我们考虑一下

根据Lucas定理,C(n,k) % p = C(n%p,k%p) * C(n/p,k/p) % p

那么整个矩阵就像分形一样这样分下来

所以对于pn*pn的矩阵而言,和是C(k+p,k+1)n

那么事情简单了,根据高中数学

x + x2 + x3 + .... + xn = x(xn-1)/(x-1)

所以我们只要快速求C就行了

我们枚举k,每次C根据上一次C来求

C(k+p,k+1) = (k+p)! / (k+1)! / (p-1)!

所以每次我们k增加了,求乘k+p再除以k+1就好

综上可以求出答案

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int modo=1000000007;
int power(int x,int y)
{
    if (y==0) return 1;
    int t=power(x,y/2);
    t=(long long)t*t%modo;
    if (y%2==1)
    {
        t=(long long)t*x%modo;
    }
    return t;
}
int anti_fact[200005];
bool not_prime[2000005];
int prime[200005];
int main()
{
    int t;
    scanf("%d",&t);
    int n,cc,k;
    int i;
    int cnt=0;
    for (i=2;i<=2000000;i++)
    {
        if (!not_prime[i])
        {
            prime[cnt++]=i;
            int j;
            if (i>=10000) continue;
            for (j=i*i;j<=2000000;j+=i)
            {
                not_prime[j]=true;
            }
        }
    }
    for (i=1;i<=200000;i++)
    {
        anti_fact[i]=power(i,modo-2);
    }
    for (i=0;i<t;i++)
    {
        scanf("%d%d%d",&cc,&n,&k);
        if ((n>1000000000)||(cc>100000)||(k>100000)||(cc<0)||(k<0)||(n<0))
        {
            for(;;);
        }
        int p=prime[cc-1];
        int sum=0;
        int j;
        int p1=p;
        int p2=(long long)(n+1)*n/2%modo;
        for (j=1;j<=k;j++)
        {
            p1=(long long)p1*(j+p)%modo*anti_fact[j+1]%modo;
            if (p1==1)
            {
                sum=(sum+(long long)p1*n%modo)%modo;
            }
            else
            {
                sum=(sum+(long long)p1*(power(p1,n)-1)%modo*power(p1-1,modo-2)%modo)%modo;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

  

posted on 2018-08-11 16:35  absi2011  阅读(138)  评论(0编辑  收藏  举报