今天得分:0+5+60(打表yyds!)
T1
题目大意:给你n种砖块,每种砖块有a[i]块。有两种操作,第一种是选定一个长度,消除这个长度的长度个砖块,若该长度砖块个数<长度, 那么只消除一个。第二种是选择一个砖块,将它拆成两个长度之和为原长度的砖块(两砖块长度非0且这两个砖块的长度至少有一个为奇数)。两人轮流操作,先不能操作的人输。问先手是否必胜。n<=1e6,a<=1e9。
题解:把奇数和偶数分开来算,奇数部分的sg函数为所有奇数位置之和mod 2,每一个偶数位置的sg函数为 2(n%(x+1)==x),1((n%(x+1))%==1),0((n%(x+1))%==0),异或即可。时间复杂度O(N)。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
inline int re_ad()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+(ch^48),ch=getchar();
return x*f;
}
int n;
int a[1000010],sg;
int main()
{
freopen("extension.in","r",stdin);
freopen("extension.out","w",stdout);
register int i,nu=0;
n=re_ad();for(i=1;i<=n;++i)a[i]=re_ad();
for(i=1;i<=n;++i)
{
if(i&1)nu+=a[i]&1;
else
{
if(a[i]%(i+1)==i)sg^=2;else sg^=(a[i]%(i+1))&1;
}
}
sg^=nu&1;
if(sg){puts("tomato fish+1s");}else puts("rainy day+1s");
return 0;
}
T2
题目大意:有一棵有根树,你要维护以下操作: 1 x z ,表示把节点 x 的父亲边(x,fax)删掉,并连边(x,z)。数据保证不会形成环。 2 x ,表示把 x 的所有儿子的儿子 y 的父亲边(y,fay)删掉,并连边(y,x)。 3 x ,把根换为 x。 每次操