CA娘出一场比赛就身败名裂….
第一题:给定一个数集,如果能使用其中的数相加得到任意自然数(每一个数可以使用多次),输出”YES”,否则输出”NO”。
大水题…
直接判断是否有
1
就行了啊…
然后交一发,WA辣…
然后一看300多次提交一个过的都木有…然后在Discuss中说道
第二题:对于一条
一开始以为是类欧几里得算法(ps:本弱不会写),然后仔细一看,这个三角形难道不是一个等腰直角三角形吗?╮(╯_╰)╭
整点个数:
由于
p,q
的范围太大,所以我们要用快速乘来计算。
吐槽:我真是醉了,这种题都有人不写long long,然而窝却和他不在同一个房间…
#include <iostream>
#include <cstdio>
#define LL long long int
using namespace std;
LL q, p;
LL mul(LL a,LL pos)
{
//由于没写a%=p,本辣鸡就终测挂辣
a%=p;
LL ans=0;
for(;pos;pos>>=1)
{
if(pos&1)
{
ans+=a;
if(ans>=p)ans-=p;
}
a+=a;
if(a>=p)a-=p;
}
return ans;
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
cin>>q>>p;
p*=2;
q-=2;
cout<<mul(q+1,q)/2 <<endl;
}
return 0;
}
第三题:
fn
肯定是
a
的若干次幂,所以首先特判
单独观察指数。
于是很容易就得到一个递推式:
这不就是矩阵快速幂吗?
由于 p 是素数,所以在指数上的模数就是
然而本辣鸡被卡常数,终测TLE辣…
#include <iostream>
#include <cstdio>
#include <cstring>
#define LL long long int
using namespace std;
LL n, a, b, c, mod, mod2;
LL power(LL a,LL pos)
{
LL ans=1;
for(;pos;pos>>=1, a=a*a%mod)
if(pos&1)ans=ans*a%mod;
return ans;
}
struct mat
{
int num[15][15],h,l;
void init(){h=l=0, memset(num,0,sizeof(num));}
mat operator * (const mat &a) const
{
mat b;b.init();
b.h=h,b.l=a.l;
for(int i=1;i<=h;++i)
for(int j=1;j<=a.l;++j)
for(int k=1;k<=l;++k)
b.num[i][j]=(b.num[i][j]+num[i][k]*a.num[k][j])%mod2;
return b;
}
}temp,tmp;
mat cal(mat &a,LL pos)
{
mat ans=a;
for(;pos;pos>>=1, a=a*a)
if(pos&1)ans=ans*a;
return ans;
}
LL solve(LL n)
{
tmp.init();
tmp.h=3, tmp.l=1, tmp.num[1][1]=0, tmp.num[2][1]=b, tmp.num[3][1]=b;
temp.init();
temp.h=temp.l=3;
temp.num[1][2]=temp.num[2][1]=temp.num[2][3]=temp.num[3][3]=1, temp.num[2][2]=c;
tmp=cal(temp,n-3)*tmp;
return tmp.num[2][1];
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
cin>>n>>a>>b>>c>>mod;
mod2=mod-1;
if(n==1)puts("1");
else if(n==2)cout<<power(a,b)<<endl;
else if(a%mod==0)puts("0");
else cout<<power(a,solve(n))<<endl;
}
return 0;
}
第四题: Fye找到了
n
个同学,把他们围成一个圈,让他们做约瑟夫游戏,然后她得到了一个同学们出圈的编号序列。游戏是这样进行的:以同学
如今Fye找到了你,她想让你告诉他满足已知出圈序列的最小的
很容易就得到了
n
<script type="math/tex" id="MathJax-Element-2027">n</script>个同余方程组,然而模数并不是两两互质的,即普通的中国剩余定理是用不上的了…
所以上另一个解同余方程的模板吧…
后记:由于出题人题意不清,导致众多选手WA了无数发…
#include <iostream>
#include <cstdio>
#define LL long long int
using namespace std;
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
if(!b)d=a, x=1, y=0;
else
{
exgcd(b,a%b,d,y,x);
y-=a/b*x;
}
}
void solve(LL b[],LL n[],int num)
{
bool flag=0;
LL n1=n[0], n2, b1=b[0], b2, bb, d, t, k, x, y;
for(int i=1;i<num;++i)
{
n2=n[i], b2=b[i], bb=b2-b1;
exgcd(n1,n2,d,x,y);
if(bb%d){flag=1;break;}
k=bb/d*x, t=n2/d;
if(t<0)t=-t;
k=(k%t+t)%t;
b1+=n1*k, n1=n1/d*n2;
}
b1%=n1;
if(flag){puts("Creation August is a SB!");return;}
else if(b1==0)b1=n1;
cout<<b1<<endl;
}
LL b[105], mod[105];
int a[105], l[105], r[105], c[105];
int main()
{
int cas, n;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",&c[i]);
a[c[i]]=i;
}
for(int j=2;j<=n;++j)l[j]=j-1;
l[1]=n;
for(int j=1;j<n;++j)r[j]=j+1;
r[n]=r[0]=1;
int now=0;
for(int i=1;i<=n;++i)
{
mod[i-1]=n-i+1;
int cnt=0;
while(now!=a[i])
now=r[now], ++cnt;
b[i-1]=cnt;
l[r[now]]=l[now];
r[l[now]]=r[now];
}
solve(b,mod,n);
}
return 0;
}