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;
}
浙公网安备 33010602011771号