大意:兩人輪流給樹黑白染色(白先手),若最終存在一個白點周圍都是白點,白勝,問勝負c++
題解:ide
1 #include<bits/stdc++.h> 2 #define FOR(i,a,b) for (register int i=(a);i<=(b);i++) 3 #define For(i,a,b) for (register int i=(a);i>=(b);i--) 4 #define mem(i,j) memset(i,j,sizeof(i)) 5 #define GO(u) for (register int j=f[u];j!=-1;j=nxt[j]) 6 #define fi first 7 #define se second 8 #define pii pair<int,int> 9 #define MP make_pair 10 using namespace std; 11 typedef long long ll; 12 const int N=1e5+5; 13 int n,a,b,lf[N],d[N],rt; 14 int tot=0,f[N],nxt[N<<1]; 15 struct E 16 { 17 int u,v; 18 }e[N<<1]; 19 inline void add(int u,int v) 20 { 21 tot++; 22 nxt[tot]=f[u]; 23 f[u]=tot; 24 e[tot]=(E){u,v}; 25 return; 26 } 27 inline int read() 28 { 29 int x=0,f=1; 30 char c=getchar(); 31 while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} 32 while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 33 return f*x; 34 } 35 inline void write(int x) 36 { 37 if (x<0) putchar('-'),x=-x; 38 if (x>9) write(x/10); 39 putchar(x%10+'0'); 40 return; 41 } 42 inline void yes() {printf("First\n");exit(0);} 43 inline void no() {printf("Second\n");exit(0);} 44 inline int dfs(int u,int fa) 45 { 46 int cnt=0; 47 GO(u) 48 { 49 int v=e[j].v; 50 if (v==fa) continue; 51 cnt+=dfs(v,u); 52 } 53 if (cnt>1) yes(); 54 return cnt^1; 55 } 56 int main() 57 { 58 mem(f,-1); 59 n=read(); 60 if (n==2) no(); 61 if (n==1) yes(); 62 FOR(i,1,n-1) a=read(),b=read(),add(a,b),add(b,a),d[a]++,d[b]++; 63 FOR(i,1,n) lf[i]=(d[i]==1); 64 FOR(i,1,n) if (!lf[i]) {rt=i;break;} 65 if (dfs(rt,0)) yes(); 66 no(); 67 return 0; 68 }
大意:有$n$個數,兩我的輪流操做,每次操做選擇一個數減一後全部數除以他們的$GCD$,所有數變爲$1$時沒法操做(輸),問勝負spa
題解:3d
1 #include<bits/stdc++.h> 2 #define FOR(i,a,b) for (register int i=(a);i<=(b);i++) 3 #define For(i,a,b) for (register int i=(a);i>=(b);i--) 4 #define mem(i,j) memset(i,j,sizeof(i)) 5 #define GO(u) for (register int j=f[u];j!=-1;j=nxt[j]) 6 #define fi first 7 #define se second 8 #define pii pair<int,int> 9 #define MP make_pair 10 using namespace std; 11 typedef long long ll; 12 const int N=1e5+5; 13 int n,a[N],ji,ou,pos,now,gcd; 14 inline int read() 15 { 16 int x=0,f=1; 17 char c=getchar(); 18 while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} 19 while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 20 return f*x; 21 } 22 inline void write(int x) 23 { 24 if (x<0) putchar('-'),x=-x; 25 if (x>9) write(x/10); 26 putchar(x%10+'0'); 27 return; 28 } 29 inline void yes() {if (now) printf("First\n");else printf("Second\n");exit(0);} 30 inline void no() {if (now) printf("Second\n");else printf("First\n");exit(0);} 31 inline int GCD(int x,int y) 32 { 33 if (!y) return x; 34 if (x<y) return GCD(y,x); 35 return GCD(y,x%y); 36 } 37 inline void solve() 38 { 39 ou=0,ji=0; 40 FOR(i,1,n) ji+=(a[i]&1),ou+=(!(a[i]&1)); 41 if (!ou) no(); 42 if (ou&1) yes(); 43 if (!ji) no(); 44 if (ji>1) no(); 45 FOR(i,1,n) if (a[i]&1) {pos=i;break;} 46 if (a[pos]==1) no(); 47 a[pos]--; 48 gcd=a[1]; 49 FOR(i,2,n) gcd=GCD(gcd,a[i]); 50 FOR(i,1,n) a[i]/=gcd; 51 now^=1; 52 solve(); 53 return; 54 } 55 int main() 56 { 57 now=1; 58 n=read(); 59 FOR(i,1,n) a[i]=read(); 60 solve(); 61 return 0; 62 }
大意:長度爲$2000$值域爲$10^8$的序列,兩我的分別對其操做一次,第一我的任意安排順序,第二我的任意次交換相鄰的互質的數,前者但願最終字典序最小,後者但願最終字典序最大,問最終序列code
題解:blog
1 #include<bits/stdc++.h> 2 #define FOR(i,a,b) for (register int i=(a);i<=(b);i++) 3 #define For(i,a,b) for (register int i=(a);i>=(b);i--) 4 #define mem(i,j) memset(i,j,sizeof(i)) 5 #define GO(u) for (register int j=f[u];j!=-1;j=nxt[j]) 6 #define fi first 7 #define se second 8 #define pii pair<int,int> 9 #define MP make_pair 10 #define pb push_back 11 using namespace std; 12 typedef long long ll; 13 const int N=2020; 14 int n,a[N],vis[N],cnt=0,ans[N],du[N]; 15 vector<int> vec[N],G[N]; 16 priority_queue <pii> q; 17 inline int read() 18 { 19 int x=0,f=1; 20 char c=getchar(); 21 while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} 22 while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 23 return f*x; 24 } 25 inline void write(int x) 26 { 27 if (x<0) putchar('-'),x=-x; 28 if (x>9) write(x/10); 29 putchar(x%10+'0'); 30 return; 31 } 32 inline int GCD(int x,int y) 33 { 34 if (!y) return x; 35 if (x<y) return GCD(y,x); 36 return GCD(y,x%y); 37 } 38 inline void dfs(int u) 39 { 40 vis[u]=1; 41 FOR(i,0,(int)vec[u].size()-1) 42 { 43 int v=vec[u][i]; 44 if (vis[v]) continue; 45 G[u].pb(v); 46 du[v]++; 47 dfs(v); 48 } 49 return; 50 } 51 bool cmp(const int x,const int y) {return a[x]<a[y];} 52 int main() 53 { 54 n=read(); 55 FOR(i,1,n) a[i]=read(); 56 sort(a+1,a+n+1);//1 57 FOR(i,1,n) FOR(j,1,n) if (i!=j) if (GCD(a[i],a[j])>1) vec[i].pb(j); 58 // FOR(i,1,n) sort(vec[i].begin(),vec[i].end()); //2 59 FOR(i,1,n) if (!vis[i]) 60 { 61 dfs(i); 62 q.push(MP(a[i],i)); 63 } 64 while (q.size()) 65 { 66 pii tmp=q.top(); 67 q.pop(); 68 ans[++ans[0]]=tmp.fi; 69 FOR(i,0,(int)G[tmp.se].size()-1) 70 { 71 int v=G[tmp.se][i]; 72 du[v]--; 73 if (!du[v]) q.push(MP(a[v],v)); 74 } 75 } 76 FOR(i,1,n) write(ans[i]),putchar(' '); 77 return 0; 78 }
大意:給出$200$個點,請你求出全部合法點集的權值和,一個點集合法即這些點剛好是某個凸包的頂點集,一個合法點集的權值定義以下,設在凸包之中的點數爲$n$(包括邊間和頂點),其值爲$2^{n-|S|}$排序
題解:ci
1 #include<bits/stdc++.h> 2 #define FOR(i,a,b) for (register int i=(a);i<=(b);i++) 3 #define For(i,a,b) for (register int i=(a);i>=(b);i--) 4 #define mem(i,j) memset(i,j,sizeof(i)) 5 #define GO(u) for (register int j=f[u];j!=-1;j=nxt[j]) 6 #define fi first 7 #define se second 8 #define pii pair<int,int> 9 #define MP make_pair 10 #define pb push_back 11 using namespace std; 12 typedef long long ll; 13 const int N=205; 14 const int mod=998244353; 15 int n,x[N],y[N],ans=0,er[N]; 16 inline int read() 17 { 18 int x=0,f=1; 19 char c=getchar(); 20 while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} 21 while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 22 return f*x; 23 } 24 inline void write(int x) 25 { 26 if (x<0) putchar('-'),x=-x; 27 if (x>9) write(x/10); 28 putchar(x%10+'0'); 29 return; 30 } 31 int main() 32 { 33 n=read(); 34 FOR(i,1,n) x[i]=read(),y[i]=read(); 35 er[0]=1; 36 FOR(i,1,n) er[i]=2LL*er[i-1]%mod; 37 ans=(1LL*er[n]-1-n+mod)%mod; 38 FOR(i,1,n) FOR(j,1,i-1) 39 { 40 int cnt=0; 41 FOR(k,1,j-1) if (1LL*((y[i]-y[j])*(x[j]-x[k]))==1LL*((x[i]-x[j])*(y[j]-y[k]))) cnt++; 42 ans=(1LL*ans-er[cnt]+mod)%mod; 43 } 44 write(ans); 45 return 0; 46 }
大意:給出長度$n\leq 10^5$值域$[1,n]$的序列$a$,構造排列$p$,使得對於任意$i$都有$p_i=a_i或p_{p_i}=a_i$,問有多少種能構造出來的排列$p$get
題解:it
1 #include<bits/stdc++.h> 2 #define FOR(i,a,b) for (register int i=(a);i<=(b);i++) 3 #define For(i,a,b) for (register int i=(a);i>=(b);i--) 4 #define mem(i,j) memset(i,j,sizeof(i)) 5 #define GO(u) for (register int j=f[u];j!=-1;j=nxt[j]) 6 #define fi first 7 #define se second 8 #define pii pair<int,int> 9 #define MP make_pair 10 #define pb push_back 11 using namespace std; 12 typedef long long ll; 13 const int N=1e6+5; 14 const int mod=1e9+7; 15 int n,a[N],du[N],cnt=0,vis[N],cir[N],tag[N],len[N],lth[N],s[N]; 16 int fac[N],inv[N],er[N],stck[N],top=0,ans=1; 17 int tot=0,f[N],nxt[N]; 18 struct E 19 { 20 int u,v; 21 }e[N]; 22 inline int read() 23 { 24 int x=0,f=1; 25 char c=getchar(); 26 while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} 27 while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 28 return f*x; 29 } 30 inline void write(int x) 31 { 32 if (x<0) putchar('-'),x=-x; 33 if (x>9) write(x/10); 34 putchar(x%10+'0'); 35 return; 36 } 37 inline void no() {printf("0\n");exit(0);} 38 inline int qpow(int x,int y) {int ret=1;for (;y;y>>=1,x=1LL*x*x%mod) if (y&1) ret=1LL*ret*x%mod;return ret;} 39 inline int Inv(int x) {return qpow(x,mod-2);} 40 inline void Init() 41 { 42 er[0]=fac[0]=1; 43 FOR(i,1,n) er[i]=1LL*er[i-1]*2%mod,fac[i]=1LL*fac[i-1]*i%mod; 44 inv[n]=Inv(fac[n]); 45 For(i,n-1,0) inv[i]=1LL*inv[i+1]*(i+1)%mod; 46 return; 47 } 48 inline int C(int x,int y) 49 { 50 int ret=1LL*fac[x]*inv[y]%mod*inv[x-y]%mod; 51 return ret; 52 } 53 inline void Work1()//找環+判無解 54 { 55 queue <int> Q; 56 while (Q.size()) Q.pop(); 57 int d[N]; 58 FOR(i,1,n) d[i]=du[i]; 59 FOR(i,1,n) if (!d[i]) Q.push(i); 60 while (Q.size()) 61 { 62 int tmp=Q.front();Q.pop(); 63 d[a[tmp]]--; 64 if (!d[a[tmp]]) Q.push(a[tmp]); 65 vis[tmp]=-1; 66 } 67 FOR(i,1,n) if (vis[i]==0) 68 { 69 int now=i; 70 cnt++; 71 while (!vis[now]) vis[now]=1,cir[now]=cnt,now=a[now]; 72 } 73 FOR(i,1,n) if (vis[i]==-1) if (du[i]>1) no(); 74 FOR(i,1,n) if (vis[i]==1) if (du[i]>2) no(); 75 // printf("vis : ");FOR(i,1,n) printf("%d ",vis[i]);putchar('\n'); 76 // printf("cir : ");FOR(i,1,n) printf("%d ",cir[i]);putchar('\n'); 77 return; 78 } 79 inline void add(int u,int v) 80 { 81 tot++; 82 nxt[tot]=f[u]; 83 f[u]=tot; 84 e[tot]=(E){u,v}; 85 return; 86 } 87 inline int dfs(int u,int fa) {GO(u) if (e[j].v!=fa&&!cir[e[j].v]) return dfs(e[j].v,u)+1;return 0;} 88 inline void Work2()//找基環樹+找鏈長度+按長度統計環 89 { 90 FOR(i,1,n) add(a[i],i); 91 FOR(i,1,n) vis[i]=0; 92 FOR(i,1,n) if (cir[i]) if (!vis[i]) 93 { 94 int now=i,jihuan=0,l=0; 95 while (!vis[now]) 96 { 97 vis[now]=1; 98 GO(now) if (!cir[e[j].v]) jihuan=1; 99 len[now]=dfs(now,0); 100 now=a[now]; 101 l++; 102 } 103 tag[cir[i]]=jihuan; 104 if (!jihuan) lth[cir[i]]=l; 105 } 106 FOR(i,1,cnt) s[lth[i]]++; 107 // printf("tag : ");FOR(i,1,cnt) printf("%d ",tag[i]);putchar('\n'); 108 // printf("len : ");FOR(i,1,n) printf("%d ",len[i]);putchar('\n'); 109 // printf("lth : ");FOR(i,1,cnt) printf("%d ",lth[i]);putchar('\n'); 110 return; 111 } 112 int aa[N],bb[N]; 113 inline void DP(int u) 114 { 115 aa[0]=bb[0]=0; 116 int val=1; 117 while (!len[u]) u=a[u]; 118 int st=u; 119 u=a[u]; 120 int step=1; 121 while (u!=st) 122 { 123 while (!len[u]) step++,u=a[u]; 124 bb[++bb[0]]=step; 125 aa[++aa[0]]=len[u]; 126 step=0; 127 if (u!=st) u=a[u],step++; 128 } 129 FOR(i,1,aa[0]) 130 { 131 if (aa[i]>bb[i]) val=0; 132 else if (aa[i]<bb[i]) val=2LL*val%mod; 133 } 134 stck[++top]=val; 135 return; 136 } 137 inline void Solve(int x) 138 { 139 int val=0; 140 if ((x&1)&&(x!=1)) FOR(i,1,s[x]/2) val=(1LL*val+1LL*C(s[x],2*i)*C(2*i,i)%mod*fac[i]%mod*qpow(x,i)%mod*er[s[x]-2*i]%mod*Inv(er[i])%mod)%mod; 141 else FOR(i,1,s[x]/2) val=(1LL*val+1LL*C(s[x],2*i)*C(2*i,i)%mod*fac[i]%mod*qpow(x,i)%mod*Inv(er[i])%mod)%mod; 142 if ((x&1)&&(x!=1)) val=(1LL*val+er[s[x]])%mod; 143 else val=(1LL*val+1)%mod; 144 stck[++top]=val; 145 return; 146 } 147 int used[N]; 148 inline void Work3()//統計每一個連通塊的方案數 149 { 150 mem(used,0); 151 FOR(i,1,n) vis[i]=0; 152 FOR(i,1,n) if (cir[i]&&(!lth[cir[i]])&&(!vis[cir[i]])) DP(i),vis[cir[i]]=1;//基環樹 153 FOR(i,1,cnt) if (lth[i]&&!used[lth[i]]) Solve(lth[i]),used[lth[i]]=1;//環 154 return; 155 } 156 int main() 157 { 158 // freopen("16.in","r",stdin); 159 // freopen("dayinf.out","w",stdout); 160 mem(f,-1); 161 n=read(); 162 FOR(i,1,n) a[i]=read(),du[a[i]]++; 163 Init(); 164 Work1(); 165 Work2(); 166 Work3(); 167 FOR(i,1,top) ans=1LL*ans*stck[i]%mod; 168 write(ans); 169 return 0; 170 }
大意:給出一個$n \leq 1000$個點$m \leq 200000$條邊的有向圖,對於每條邊詢問,若將這條邊反向,整個圖的強聯通份量個數是否會變
題解:
1 #include<bits/stdc++.h> 2 namespace csx_std { 3 using namespace std; 4 typedef long long ll; 5 #define FOR(i,a,b) for (register int i=(a);i<=(b);i++) 6 #define For(i,a,b) for (register int i=(a);i>=(b);i--) 7 #define mem(i,j) memset(i,j,sizeof(i)) 8 #define pii pair<int,int> 9 #define pb push_back 10 #define MP make_pair 11 #define fi first 12 #define se second 13 #define GO(u) for (register int j=f[u];j!=-1;j=nxt[j]) 14 const int N=1e3+5; 15 const int M=2e5+5; 16 const int mod=1e9+7; 17 inline int qpow(int x,int y) {int ret=1;for (;y;y>>=1,x=1LL*x*x%mod) if (y&1) ret=1LL*ret*x%mod;return ret;} 18 inline int Inv(int x) {return qpow(x,mod-2);} 19 inline void upd(int &x,int y) {x=(1LL*x+y)%mod;return;} 20 inline int chkmax(int &x,int y) {return (x<y)?(x=y,1):0;} 21 inline int chkmin(int &x,int y) {return (x>y)?(x=y,1):0;} 22 inline int read() 23 { 24 int x=0,f=1; 25 char c=getchar(); 26 while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} 27 while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 28 return f*x; 29 } 30 inline void write(int x) 31 { 32 if (x<0) x=-x,putchar('-'); 33 if (x>9) write(x/10); 34 putchar(x%10+'0'); 35 return; 36 } 37 } 38 using namespace csx_std; 39 int n,m,tmp1,tmp2,num[N][N],con[N][N],con_con[N][N],vis[N],p[N],q[N],uu[M],vv[M],cnt=0,ans[M]; 40 int tot=0,f[N],nxt[M]; 41 vector <int> G[N]; 42 #define v G[u][i] 43 inline void dfs(int u,int fa) 44 { 45 con[fa][u]=1; 46 vis[u]=1; 47 FOR(i,0,(int)G[u].size()-1) if (!vis[v]) dfs(v,fa); 48 return; 49 } 50 inline void dfs1(int u) 51 { 52 vis[u]=1; 53 FOR(i,0,(int)G[u].size()-1) if (!vis[v]) p[v]=num[u][v],dfs1(v); 54 return; 55 } 56 inline void dfs2(int u) 57 { 58 vis[u]=1; 59 For(i,(int)G[u].size()-1,0) if (!vis[v]) q[v]=num[u][v],dfs2(v); 60 return; 61 } 62 #undef v 63 int main() 64 { 65 mem(f,-1); 66 n=read(),m=read(); 67 FOR(i,1,m) tmp1=read(),tmp2=read(),G[tmp1].pb(tmp2),uu[i]=tmp1,vv[i]=tmp2,num[tmp1][tmp2]=++cnt; 68 FOR(i,1,n) {FOR(j,1,n) vis[j]=0;dfs(i,i);} 69 FOR(i,1,n) 70 { 71 FOR(j,1,n) p[j]=q[j]=0; 72 FOR(j,1,n) vis[j]=0; 73 dfs1(i); 74 FOR(j,1,n) vis[j]=0; 75 dfs2(i); 76 FOR(j,0,(int)G[i].size()-1) 77 { 78 int v=G[i][j]; 79 if (p[v]!=num[i][v]||q[v]!=num[i][v]) con_con[i][v]=1; 80 } 81 } 82 FOR(i,1,m) if (con[vv[i]][uu[i]] xor con_con[uu[i]][vv[i]]) ans[i]=1; 83 FOR(i,1,m) 84 if (ans[i]) puts("diff"); 85 else puts("same"); 86 return 0; 87 }