前言
- T1T2都是送分题太让蒟蒻感动啦。
- T3工程题太让我感动啦。
- 还有给出的fread让我意识到fread的数组大小好像跟数据没什么关系??
T1
- 特判题。
- 时间复杂度$Theta(logN)$,空间复杂度$Theta(1)$。
#include<cstdio> #define ll long long #define getchar() ((S==T&&(T=(S=buf)+fread(buf,1,L,stdin),S==T))?EOF:*S++) #define jp {puts("0");goto ac;} int const L=1<<20|1; char buf[L],*S,*T; inline int read(){ int ss(0),pp(1);char bb(getchar()); for(;bb<48||bb>57;bb=getchar())if(bb=='-')pp=-1; while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar(); return ss*pp; } int main(){ //freopen("ex_bit.in","r",stdin); //freopen("1.out","w",stdout); int T=read(); while(T--){ int andr=read(),orr=read(),xorr=read(),a,o,x; long long ans=1; if(~orr){ if(~andr && ~xorr){ while(andr || orr || xorr){ a=andr&1,o=orr&1,x=xorr&1; if((!o && x) || (!a && o && !x) || (a && !o) || (a && x))jp if(!a && o && x)ans<<=1; andr>>=1,orr>>=1,xorr>>=1; } printf("%lld ",ans); continue; } if(~andr){ while(andr || orr){ a=andr&1,o=orr&1; if(a && !o)jp if(!a && o)ans<<=1; andr>>=1,orr>>=1; } printf("%lld ",ans); continue; } if(~xorr){ while(orr || xorr){ o=orr&1,x=xorr&1; if(!o && x)jp if(o && x)ans<<=1; orr>>=1,xorr>>=1; } printf("%lld ",ans); continue; } while(orr){ if(orr&1)ans*=3; orr>>=1; } printf("%lld ",ans); continue; } if(andr==-1 || xorr==-1){puts("inf");continue;} while(andr || xorr){ a=andr&1,x=xorr&1; if(a && x)jp if(!a && x)ans<<=1; andr>>=1,xorr>>=1; } printf("%lld ",ans); ac:; } return 0; }
T2
- 模拟题。难度略高于数组练习。
- 开桶出现负下标?初始mark值设成-2e6。
- 时空复杂度$Theta(N)$。
#include<cstdio> #define ll long long #define getchar() ((S==T&&(T=(S=buf)+fread(buf,1,L,stdin),S==T))?EOF:*S++) int const L=1<<20|1,N=1e7+5; char buf[L],*S,*T; inline int read(){ int ss(0),pp(1);char bb(getchar()); for(;bb<48||bb>57;bb=getchar())if(bb=='-')pp=-1; while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar(); return ss*pp; } int m; ll ml=-2e6,siz,tot; int now,v[N]; int q[N]; bool vis[N]; inline void bing(){ int x=read(); for(register int i=1,y;i<=x;++i){ y=read()-ml; if(!vis[y])tot+=y,q[++siz]=y,vis[y]=1; } return ; } inline void _swap(int &x,int &y){ int z=x; x=y,y=z; return ; } inline void jiao(){ int x=read(); ++now; for(register int i=1;i<=x;++i)v[read()-ml]=now; for(register int i=1,y;i<=siz;++i){ if(v[y=q[i]]!=now){ _swap(q[i],q[siz--]); --i; vis[y]=0,tot-=y; } } return ; } int main(){ //freopen("ex_jihe4.in","r",stdin); //freopen("1.out","w",stdout); m=read(); while(m--){ int opt=read(); switch(opt){ case 1:bing();break; case 2:jiao();break; case 3:if(siz)++ml;break; case 4:if(siz)--ml;break; } printf("%lld ",ml*siz+tot); } return 0; }
T3
- 工业题。
- 直接用结构体存下状态,大力分情况容斥即可。
- 用map映射状态就行。Hash表可以更快。
- 不过真Hash会很难打,于是我打了个错的Hash,但它过了。
- 然后我就没脸的卡进了1000ms233。
- 时空复杂度$Theta(N^2)$。常数巨大。
#include<cstdio> using namespace std; #define getchar() ((S==T&&(T=(S=buf)+fread(buf,1,L,stdin),S==T))?EOF:*S++) int const L=1<<20|1,N=1003,M=1e6+5,MOD=3e6-1; long long bs=31313; char buf[L],*S,*T; const int mx[4]={0,0,1,-1}; const int my[4]={1,-1,0,0}; struct node{ int col,fir,sec,thr,fur; node(){} node(int x,int y,int xx,int yy,int kx):col(x),fir(y),sec(xx),thr(yy),fur(kx){} friend bool operator < (node B,node R){ return (B.col^R.col)?B.col<R.col:((B.fir^R.fir)?B.fir<R.fir: ((B.sec^R.sec)?B.sec<R.sec:((B.thr^R.thr)?B.thr<R.thr:B.fur<R.fur))); } }; int n,m,now; int a[N][N],vis[N][N]; int bl[N][N][4]; struct Hash_table{ int head[MOD],to[M],Next[M],w[M],ct; inline int operator [](node x){ int now=(bs*((bs*(bs*x.fir+x.sec)+x.thr)*bs%MOD+x.fur)+x.col)%MOD; for(register int i=head[now],pd=x.col;i;i=Next[i]) if(to[i]==pd)return w[i]++; to[++ct]=x.col; Next[ct]=head[now],head[now]=ct; return w[ct]++; } }mp; struct dui{ int xp,yp; dui(){} dui(int x,int y):xp(x),yp(y){} }q[M]; int t,u; long long ans; inline int read(){ int ss(0),pp(1);char bb(getchar()); for(;bb<48||bb>57;bb=getchar())if(bb=='-')pp=-1; while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar(); return ss*pp; } inline void bfs(int x,int y){ vis[x][y]=++now; q[t=1]=dui(x,y),u=0; while(u^t){ x=q[++u].xp,y=q[u].yp; for(register int i=0,tx,ty;i<4;++i) if((tx=x+mx[i])&&tx<=n&&(ty=y+my[i])&&ty<=m&&vis[tx][ty]^now){ vis[tx][ty]=now; if(!a[tx][ty])q[++t]=dui(tx,ty); else for(register int j=0;j<4;++j) if(!bl[tx][ty][j]){bl[tx][ty][j]=now;break;} } } return ; } int main(){ n=read(),m=read();read(); for(register int i=1;i<=n;++i) for(register int j=1;j<=m;++j) a[i][j]=read(); for(register int i=1;i<=n;++i) for(register int j=1;j<=m;++j) if(!a[i][j]&&!vis[i][j])bfs(i,j); for(register int i=1;i<=n;++i) for(register int j=1;j<=m;++j) if(a[i][j]){ int now=a[i][j],bl1=bl[i][j][0],bl2=bl[i][j][1], bl3=bl[i][j][2],bl4=bl[i][j][3]; if(bl1)ans+=mp[node(now,bl1,0,0,0)]; if(bl2)ans+=mp[node(now,bl2,0,0,0)] -mp[node(now,bl1,bl2,0,0)]; if(bl3)ans+=mp[node(now,bl3,0,0,0)] +mp[node(now,bl1,bl2,bl3,0)] -mp[node(now,bl1,bl3,0,0)] -mp[node(now,bl2,bl3,0,0)]; if(bl4)ans+=mp[node(now,bl1,bl2,bl4,0)] +mp[node(now,bl1,bl3,bl4,0)] +mp[node(now,bl2,bl3,bl4,0)] +mp[node(now,bl4,0,0,0)] -mp[node(now,bl1,bl2,bl3,bl4)] -mp[node(now,bl1,bl4,0,0)] -mp[node(now,bl2,bl4,0,0)] -mp[node(now,bl3,bl4,0,0)]; } for(register int i=1;i<=n;++i) for(register int j=1;j<m;++j) if(a[i][j] && a[i][j]==a[i][j+1]){ for(register int k=0;k<4&&bl[i][j][k];++k) for(register int o=0,e=bl[i][j][k];o<4&&bl[i][j+1][k];++o) if(bl[i][j+1][o]==e)goto ac; ++ans; ac:; } for(register int i=1;i<n;++i) for(register int j=1;j<=m;++j) if(a[i][j] && a[i][j]==a[i+1][j]){ for(register int k=0;k<4&&bl[i][j][k];++k) for(register int o=0,e=bl[i][j][k];o<4&&bl[i+1][j][k];++o) if(bl[i+1][j][o]==e)goto ak; ++ans; ak:; } printf("%lld",ans); return 0; }