[2016北京集训试题6]mushroom-[bitset]
Description
Solution
bitset是个好东西啊。。强行压位什么的真是够orz。
由于所有的蘑菇上房间的长相是一样的,我们针对每个房间,算出它到根节点的bitset和以它为根的子树的bitset。
每次新开一个蘑菇,为了防止被卡空间,我们只是把指针指向蘑菇u的bitset,并且cnt[u]++。只有当对这个新蘑菇进行操作的时候,才给它单独开一个 bitset。
本题的题解一句话-优雅的暴力。
Code
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> using namespace std; typedef unsigned int ui; int n,q,T; struct G{int y,nxt;}g[100010];int h[50010],tot=0; int fa[50010][17],dep[50010]; ui up[50010][1610],down[50010][1610]; void dfs(int x,int f) { fa[x][0]=f;dep[x]=dep[f]+1; for (int i=1;i<=16;i++) fa[x][i]=fa[fa[x][i-1]][i-1]; for (int i=0;i<T;i++) up[x][i]=up[f][i]; up[x][x>>5]|=1u<<(x&31); for (int i=h[x];i;i=g[i].nxt) if (g[i].y!=f) dfs(g[i].y,x); down[x][x>>5]|=1u<<(x&31); for (int i=0;i<T;i++) down[f][i]|=down[x][i]; } int lca(int x,int y) { if (dep[x]<dep[y]) swap(x,y); for (int i=16;i>=0;i--) if (dep[fa[x][i]]>dep[y]) x=fa[x][i]; if (dep[x]>dep[y]) x=fa[x][0]; if (x==y) return x; for (int i=16;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } int bin[100010]; ui *_bit[100010];int _new=1; map<ui*,int>cnt; void init_bit() { ++cnt[_bit[1]=(ui*)malloc(T*sizeof(ui))]; for (int i=0;i<T;i++) _bit[1][i]=0; for (int i=1;i<=n;i++) _bit[1][i>>5]|=1u<<(i&31); } void query(ui *b,int w) { int cost=0;w++; for (int i=1;i<=n;) if (b[i>>5]>>(i&31)) { ui re=b[i>>5]>>(i&31)<<(i&31),k=re&-re; if (k>65536) k=bin[k>>16]+16;else k=bin[k]; cost++,i=(i&(~31u)|k)+w; } else i=(i>>5)+1<<5; printf("%d\n",cost); } void clear_bit(int u,int x,int y) { if (y-x<=32) {for (int i=x;i<=y;i++) _bit[u][i>>5]&=~(1u<<(i&31));return;} int l=x>>5,r=y>>5;l++;r--; for (int i=l;i<=r;i++) _bit[u][i]=0; for (int i=x;i>>5<l;i++) _bit[u][i>>5]&=~(1u<<(i&31)); for (int i=y;i>>5>r;i--) _bit[u][i>>5]&=~(1u<<(i&31)); } int t,u,v,x,y,w; int main() { scanf("%d",&n);T=(n+32)>>5; for (int i=1;i<n;i++) { scanf("%d%d",&x,&y); g[++tot]=G{y,h[x]};h[x]=tot; g[++tot]=G{x,h[y]};h[y]=tot; } dfs(1,0);init_bit(); for (int i=0;i<=16;i++) bin[1<<i]=i; scanf("%d",&q); while (q--) { scanf("%d",&t);scanf("%d",&u); if (t==1){ ++cnt[_bit[++_new]=_bit[u]];} else if (t==9){scanf("%d",&w);query(_bit[u],w);} else { if (cnt[_bit[u]]>1) { ui* c=_bit[u]; cnt[c]--; _bit[u]=(ui*)malloc(T*sizeof(ui)); for (int i=0;i<T;i++) _bit[u][i]=c[i]; cnt[_bit[u]]++; } if (t==2) { scanf("%d",&v); for (int i=0;i<T;i++) _bit[u][i]|=_bit[v][i]; } if (t==3) { scanf("%d",&x); for (int i=0;i<T;i++) _bit[u][i]&=~down[x][i]; } if (t==4) { scanf("%d",&x); for (int i=0;i<T;i++) _bit[u][i]&=down[x][i]; } if (t==5) { scanf("%d%d",&x,&y); int LCA=lca(x,y); for (int i=0;i<T;i++) _bit[u][i]&=~(up[x][i]^up[y][i]); _bit[u][LCA>>5]&=~(1u<<(LCA&31)); } if (t==6) { scanf("%d%d",&x,&y); int LCA=lca(x,y); ui c=_bit[u][LCA>>5]>>(LCA&31)&1; for (int i=0;i<T;i++) _bit[u][i]&=up[x][i]^up[y][i]; _bit[u][LCA>>5]|=c<<(LCA&31); } if (t==7){scanf("%d%d",&x,&y);clear_bit(u,x,y);} if (t==8){scanf("%d%d",&x,&y);clear_bit(u,1,x-1);clear_bit(u,y+1,n);} } } }