【树链剖分】LGP3613 睡觉困难综合征
来源:互联网 发布:python 迭代器 定义 编辑:程序博客网 时间:2024/04/30 21:06
原题地址
【题目大意】
不想打了。
【题目分析】
每一位不会互相影响,可以把每一位分开考虑。
还要用unsigned long long。
【解题思路】
将每一位分开以后修改好啊,直接改就好了。
询问的时候算出来每一位填0,1经过这条链的变换之后得到的值。
我们发现从高位往低位走的时候,如果这一位填0可以得到1,那么填0一定是最优的。
否则如果可以填1,就把这一位填为1。
复杂度是
然后我们决定把这个k搞掉。
只要把k位一起算就可以了,多维护几个值就好。
复杂度是
【代码】
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef unsigned long long ULL;const ULL mx=0-1;const int MAXN=2e5+10;int n,m,k,tot,sz;int opt[MAXN],siz[MAXN],dep[MAXN],q[MAXN],pos[MAXN];int head[MAXN],top[MAXN],son[MAXN],fa[MAXN];ULL val[MAXN],cf[MAXN];struct Tway{ int v,nex;};Tway e[MAXN<<1];struct Tree{ ULL v0,v1,w0,w1;};Tree tree[MAXN<<2],ans0[MAXN],ans1[MAXN];inline void add(int u,int v){ ++tot; e[tot].v=v;e[tot].nex=head[u];head[u]=tot;}inline void dfs0(int u,int f){ siz[u]=1;dep[u]=dep[f]+1; for(int i=head[u];i;i=e[i].nex) { int v=e[i].v; if(v==f) continue; fa[v]=u; dfs0(v,u); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; }}inline void dfs1(int u,int tp){// printf("%d\n",u); top[u]=tp;pos[u]=++sz;q[sz]=u; if(!son[u]) return; dfs1(son[u],tp); for(int i=head[u];i;i=e[i].nex) { int v=e[i].v; if(v!=fa[u] && v!=son[u]) dfs1(v,v); }}inline ULL calc(ULL num,int u){ if(opt[u]==1) return num&val[u]; if(opt[u]==2) return num|val[u]; if(opt[u]==3) return num^val[u];}inline Tree update(Tree l,Tree r){ Tree tmp; tmp.v0=tmp.v1=tmp.w0=tmp.w1=0; tmp.v0=(l.v0 & r.v1) | ((~l.v0)&r.v0); tmp.v1=(l.v1 & r.v1) | ((~l.v1)&r.v0); tmp.w0=(r.w0 & l.w1) | ((~r.w0)&l.w0); tmp.w1=(r.w1 & l.w1) | ((~r.w1)&l.w0);//typed wrong return tmp;}inline void pushup(int rt){ tree[rt]=update(tree[rt<<1],tree[rt<<1|1]);}inline void build(int rt,int l,int r){ if(l==r) { int tmp=q[l]; tree[rt].v0=tree[rt].w0=calc(0,tmp); tree[rt].v1=tree[rt].w1=calc(mx,tmp); return; } int mid=(l+r)>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); pushup(rt);}inline void changep(int rt,int l,int r,int p){ if(l==r && l==p) { int tmp=q[l]; tree[rt].v0=tree[rt].w0=calc(0,tmp); tree[rt].v1=tree[rt].w1=calc(mx,tmp); return; } int mid=(l+r)>>1; if(p<=mid) changep(rt<<1,l,mid,p); else changep(rt<<1|1,mid+1,r,p); pushup(rt);}inline Tree query(int rt,int l,int r,int L,int R){ if(L<=l && r<=R) return tree[rt]; int mid=(l+r)>>1; Tree ret;bool flag=false; if(L<=mid) ret=query(rt<<1,l,mid,L,R),flag=true; if(R>mid) if(flag) ret=update(ret,query(rt<<1|1,mid+1,r,L,R)); else ret=query(rt<<1|1,mid+1,r,L,R); return ret;}inline Tree solve(int x,int y){ int cnt0=0,cnt1=0; while(top[x]!=top[y]) { if(dep[top[x]]>dep[top[y]]) { ans0[++cnt0]=query(1,1,n,pos[top[x]],pos[x]); x=fa[top[x]]; } else { ans1[++cnt1]=query(1,1,n,pos[top[y]],top[y]); y=fa[top[y]]; } } if(dep[x]>=dep[y]) ans0[++cnt0]=query(1,1,n,pos[y],pos[x]); else ans1[++cnt1]=query(1,1,n,pos[x],pos[y]); for(int i=1;i<=cnt0;++i) swap(ans0[i].v0,ans0[i].w0),swap(ans0[i].v1,ans0[i].w1);//swap false first Tree sum; if(cnt0) { sum=ans0[1]; for(int i=2;i<=cnt0;++i) sum=update(sum,ans0[i]); if(cnt1) sum=update(sum,ans1[cnt1]); } else sum=ans1[cnt1]; for(int i=cnt1-1;i>=1;--i) sum=update(sum,ans1[i]); printf("%d %d %d %d\n",sum.v0,sum.v1,sum.w0,sum.w1); return sum;}int main(){ freopen("LGP3613.in","r",stdin); freopen("LGP3613.out","w",stdout); scanf("%d%d%d",&n,&m,&k); cf[0]=1; for(int i=1;i<=k-1;++i) cf[i]=(cf[i-1]<<1); for(int i=1;i<=n;++i) scanf("%d%llu",&opt[i],&val[i]); for(int i=1;i<n;++i) { int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u); } dfs0(1,0);dfs1(1,1); build(1,1,n); for(int i=1;i<=m;++i) { int op,u,v;ULL t; scanf("%d%d%d%llu",&op,&u,&v,&t); if(op&1) { Tree tmp=solve(u,v);ULL ret=0; for(int i=63;i>=0;--i) { ULL t0=(tmp.v0>>i)&1; ULL t1=(tmp.v1>>i)&1; if(t0>=t1 || cf[i]>t) ret|=(t0 ? cf[i] : 0); else { ret|=(t1 ? cf[i] : 0); t-=cf[i]; } } printf("%llu\n",ret); } else { opt[u]=v;val[u]=t; changep(1,1,n,pos[u]); } } return 0;}
阅读全文
0 0
- 【树链剖分】LGP3613 睡觉困难综合征
- luogu P3613 睡觉困难综合征
- 洛谷P3613:睡觉困难综合征 (LCT+二进制压位)
- [BZOJ3668]NOI2014起床困难综合征|贪心
- [UOJ#2] [NOI2014] 起床困难综合征
- 2017.10.19 起床困难综合征 思考记录
- 【NOI 2014】起床困难综合征 拆位+贪心
- 睡觉
- 睡觉
- 睡觉
- 睡觉
- 睡觉
- 手机综合征
- 洛谷3613:睡觉困难综合症(LCT+机巧的位运算)
- 困难
- 困难
- 困难
- 困难
- Java基础进阶知识点
- Java正确创建线程池方式
- svn同步时指定某些文件不显示
- laravel 学习记录
- 音频开发——录音与播放、音量调节
- 【树链剖分】LGP3613 睡觉困难综合征
- js打开word文档,而不是下载
- 物联网让智慧城市梦想成真
- tensorflow基础(二)--TF训练和变量
- 使用cmd遇到的问题
- PHP基础
- UE4蓝图节点文档翻译【目录】--- Add Event/Collision
- boost构造和解析json
- Kafka源码深度解析-系列1 -消息队列的策略与语义