BZOJ4811: [Ynoi2017]由乃的OJ(洛谷P3613)
2017-12-16 10:24
260 查看
树链剖分 位运算乱搞
BZOJ题目传送门洛谷题目传送门
前言
建议先把睡觉困难综合征这道题给做了
题解
和睡觉困难综合征一样,考虑每一位放1和放0的情况。那么我们只需要弄清楚如何合并区间就行了。
定义p0,p1表示全放0/1时经过这一个区间后会变成什么。那么在合并左右区间时就变成了这两个东西:
//y是左区间,z是右区间 x.p0=(y.p0&z.p1)|((~y.p0)&z.p0); x.p1=(y.p1&z.p1)|((~y.p1)&z.p0);
x.p0放进去后变成两种情况:即变成0或变成1。
变成1:y.p0&z.p1即表示0经过y变成1后再经过z变成的数字。
变成0:(~y.p0)&z.p0表示0经过y变成0后再经过z变成的数字。
那么x.p0就把这两种情况合起来就好了,x.p1也是如此。
左区间进,右区间出 和 右区间进,左区间出是不一样的。存储和查询的时候需要注意。
还有就是p0和p1要开unsigned long long,因为会达到264264。
代码:
#include<cctype> #include<cstdio> #include<cstring> #include<algorithm> #define N 100005 using namespace std; typedef unsigned long long ull; struct tree{ int l,r; }t[N*4]; struct dt{ ull p1,p0; }tl[N*4],tr[N*4]; struct edge{ int next,to; }ed[N*2]; int n,m,k,p,nd,h ,tp ,fa ,to ,sz ,dep ,in ,id ; ull op [2]; inline char readc(){ static char buf[100000],*l=buf,*r=buf; if (l==r) r=(l=buf)+fread(buf,1,100000,stdin); if (l==r) return EOF; return *l++; } inline ull _read(){ ull x=0; char ch=readc(); while (!isdigit(ch)) ch=readc(); while (isdigit(ch)) x=x*10+ch-48,ch=readc(); return x; } void addedge(int x,int y){ ed[++k].next=h[x],ed[k].to=y,h[x]=k; } void dfs1(int x,int depth){ sz[x]=1,dep[x]=depth; for (int i=h[x];i;i=ed[i].next) if (ed[i].to!=fa[x]){ int v=ed[i].to; fa[v]=x,dfs1(v,depth+1),sz[x]+=sz[v]; if (sz[to[x]]<sz[v]) to[x]=v; } } void dfs2(int x){ in[id[x]=++nd]=x; if (to[x]) tp[to[x]]=tp[x],dfs2(to[x]); for (int i=h[x];i;i=ed[i].next) if (ed[i].to!=fa[x]&&ed[i].to!=to[x]) tp[ed[i].to]=ed[i].to,dfs2(ed[i].to); } dt pshp(dt y,dt z){ dt ret; ret.p0=(y.p0&z.p1)|((~y.p0)&z.p0); ret.p1=(y.p1&z.p1)|((~y.p1)&z.p0); return ret; } dt updt(ull op,ull w){ dt ans; if (op==1) ans.p0=0&w,ans.p1=(~0)&w; if (op==2) ans.p0=0|w,ans.p1=(~0)|w; if (op==3) ans.p0=0^w,ans.p1=(~0)^w; return ans; } void build(int l,int r,int x){ t[x].l=l,t[x].r=r; if (l==r){ tl[x]=tr[x]=updt(op[in[l]][0],op[in[l]][1]); return; } int mid=l+r>>1; build(l,mid,x*2),build(mid+1,r,x*2+1); tl[x]=pshp(tl[x*2],tl[x*2+1]); tr[x]=pshp(tr[x*2+1],tr[x*2]); } void mdfy(int x,int p,ull op,ull w){ if (t[x].l==t[x].r){ tl[x]=tr[x]=updt(op,w); return; } int mid=t[x].l+t[x].r>>1; if (p<=mid) mdfy(x*2,p,op,w); else mdfy(x*2+1,p,op,w); tl[x]=pshp(tl[x*2],tl[x*2+1]); tr[x]=pshp(tr[x*2+1],tr[x*2]); } dt srch(int x,int l,int r,int fl){ if (t[x].l>=l&&t[x].r<=r) if (fl) return tr[x]; else return tl[x]; int mid=t[x].l+t[x].r>>1; if (r<=mid) return srch(x*2,l,r,fl); else if (l>mid) return srch(x*2+1,l,r,fl); else return pshp(srch(x*2+fl,l,r,fl),srch(x*2+1-fl,l,r,fl)); } dt find(int x,int y){ dt ans1=updt(3,0),ans2=updt(3,0); while (tp[x]!=tp[y]) if (dep[tp[x]]>=dep[tp[y]]){ ans1=pshp(ans1,srch(1,id[tp[x]],id[x],1)); x=fa[tp[x]]; } else{ ans2=pshp(srch(1,id[tp[y]],id[y],0),ans2); y=fa[tp[y]]; } if (dep[x]>=dep[y]) return pshp(pshp(ans1,srch(1,id[y],id[x],1)),ans2); else return pshp(pshp(ans1,srch(1,id[x],id[y],0)),ans2); } void nswr(int x,int y,ull z){ dt ans=find(x,y); ull state=0,ret=0; for (int i=p;i;i--) if (ans.p0&(1ull<<i-1)) ret+=1ull<<i-1; else if ((ans.p1&(1ull<<i-1)&&(1ull<<i-1)+state<=z)) ret+=1ull<<i-1,state+=1ull<<i-1; printf("%llu\n",ret); } int main(){ n=_read(),m=_read(),p=_read(); for (int i=1;i<=n;i++) op[i][0]=_read(),op[i][1]=_read(); for (int i=1;i<n;i++){ int u=_read(),v=_read(); addedge(u,v),addedge(v,u); } dfs1(1,1),tp[1]=1,dfs2(1),build(1,n,1); while (m--){ int flag=_read(),x=_read(),y=_read(); ull z=_read(); if (flag==2) mdfy(1,id[x],y,z); else nswr(x,y,z); } return 0; }
相关文章推荐
- BZOJ4811: [Ynoi2017]由乃的OJ 重链剖分
- BZOJ4811 [Ynoi2017]由乃的OJ
- BZOJ 4811 [Ynoi2017]由乃的OJ ——Link-Cut Tree
- bzoj 4811: [Ynoi2017]由乃的OJ (树链剖分)
- 4811: [Ynoi2017]由乃的OJ
- bzoj 4811: [Ynoi2017]由乃的OJ
- [YNOI2017][bzoj4811][luogu3613] 由乃的OJ/睡觉困难综合症 [压位+树链剖分+线段树]
- BZOJ-4811: [Ynoi2017]由乃的OJ (树链剖分 线段树维护区间操作值 好题)
- [树链剖分] BZOJ 4811 [Ynoi2017]由乃的OJ
- bzoj 4811: [Ynoi2017]由乃的OJ
- BZOJ4811 [Ynoi2017]由乃的OJ
- [bzoj4811] [Ynoi2017]由乃的OJ
- 【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树
- BZOJ 4811([Ynoi2017]由乃的OJ-树链剖分)
- bzoj 4810: [Ynoi2017]由乃的玉米田 莫队算法+bitset
- 洛谷Oj-Likecloud-吃、吃、吃-多维动态规划
- [洛谷P3792] 由乃与大母神原型和偶像崇拜
- [洛谷 P2891][caioj 1116][USACO07OPEN] 吃饭Dining --- dinic最大流
- 洛谷 P3723 [AH/HNOI2017]礼物(bzoj P4827 [Hnoi2017]礼物)
- BZOJ 4810 [Ynoi2017]由乃的玉米田 ——Bitset 莫队算法