前置技能:[Noi2014]起床困难综合症。

不难看出,这道题其实就是上一道题的加强版
在上一道题中,因为位运算时位与位之间互不干扰
所以从高位到低位枚举初始值二进制上的每一位为0和为1时,经过n次计算后这一位的结果,贪心选取
在这题中,我们也可以用同样的思路求取答案
因为有树上路径查询,考虑树链剖分,用线段树维护每一位初始为0和1时,经过一个区间的计算变为多少
因为&、|、^ 运算都符合结合律,所以这样做是可行的
问题是,&、|、^ 运算并不都满足交换律,即每个区间从左到右计算和从右到左计算得到的结果是不同的
而在树上从x走到y的途中,并不保证一定按dfn序从小到大的顺序走
所以我们还要分别维护每个区间从左到右计算和从右到左计算的结果
另外,给每一位都开一颗线段树显然是不现实的,
考虑到 k<=64,我们使用状压,把所有位都压到一起,存到一颗线段树中(注意要开unsigned long long)

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N=100010;
ull read(){ull x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
struct Edge{int u,v,nxt;
}edge[N<<1];
int head[N],cnt;
void addedge(int u,int v){edge[++cnt]=(Edge){u,v,head[u]};head[u]=cnt;edge[++cnt]=(Edge){v,u,head[v]};head[v]=cnt;
}
int n,m,k;
int dep[N],son[N],sz[N],top[N],fa[N],tid[N],rnk[N],ind;
void dfs1(int u,int f){fa[u]=f;dep[u]=dep[f]+1;sz[u]=1;for(int i=head[u];~i;i=edge[i].nxt) if(edge[i].v!=f){dfs1(edge[i].v,u);if(sz[edge[i].v]>sz[son[u]]) son[u]=edge[i].v;sz[u]+=sz[edge[i].v];}
}
void dfs2(int u,int tp){top[u]=tp;tid[u]=++ind;rnk[ind]=u;if(sz[u]>1) dfs2(son[u],tp);for(int i=head[u];~i;i=edge[i].nxt) if(edge[i].v!=son[u]&&edge[i].v!=fa[u])dfs2(edge[i].v,edge[i].v);
}
ull tran[N<<3][2][2];
//tran[o][0:带进0计算 ? 1:带进1计算][0:从左往右算 ? 1:从右往左算]
inline ull transf(ull a,ull b,int opt){if(opt==1){return a&b;}else if(opt==2){return a|b;}else return a^b;
}
int op;
inline ull transf(ull a,ull b){if(op==1){return a&b;}else if(op==2){return a|b;}else return a^b;
}
inline void pushup(int o){int ls=o<<1,rs=o<<1|1;tran[o][1][0]=(tran[ls][1][0]&tran[rs][1][0])|(~tran[ls][1][0]&tran[rs][0][0]);tran[o][1][1]=(tran[rs][1][1]&tran[ls][1][1])|(~tran[rs][1][1]&tran[ls][0][1]);tran[o][0][0]=(tran[ls][0][0]&tran[rs][1][0])|(~tran[ls][0][0]&tran[rs][0][0]);tran[o][0][1]=(tran[rs][0][1]&tran[ls][1][1])|(~tran[rs][0][1]&tran[ls][0][1]);
}
void update(int o,int l,int r,int x,ull k){if(l==r){tran[o][0][0]=tran[o][0][1]=transf(0ull,k);tran[o][1][0]=tran[o][1][1]=transf(~0ull,k);}else{int mid=l+r>>1;if(x<=mid) update(o<<1,l,mid,x,k);else update(o<<1|1,mid+1,r,x,k);pushup(o);  }
}
ull t1[2],t0[2];
int t;
void query(int o,int l,int r,int a,int b){if(a<=l&&b>=r){   if(!t){ull tt=t1[t];t1[t]=(tran[o][1][t]&t1[t])|(~tran[o][1][t]&t0[t]);t0[t]=(tran[o][0][t]&tt)|(~tran[o][0][t]&t0[t]);}else{t1[t]=(t1[t]&tran[o][1][t])|(~t1[t]&tran[o][0][t]);t0[t]=(t0[t]&tran[o][1][t])|(~t0[t]&tran[o][0][t]);     }}else{int mid=l+r>>1;if(b>mid) query(o<<1|1,mid+1,r,a,b);if(a<=mid) query(o<<1,l,mid,a,b);      }
}
ull val[N];
int opt[N];
void build(int o,int l,int r){if(l==r){   tran[o][0][0]=tran[o][0][1]=transf(0ull,val[rnk[l]],opt[rnk[l]]);tran[o][1][0]=tran[o][1][1]=transf(~0ull,val[rnk[l]],opt[rnk[l]]);}else{int mid=l+r>>1;build(o<<1,l,mid);build(o<<1|1,mid+1,r);pushup(o);}
}
ull z;
inline ull ask(int x,int y){t0[0]=t0[1]=0;t1[0]=t1[1]=~0ull;while(top[x]!=top[y]){if(dep[top[x]]>dep[top[y]]){t=1;query(1,1,n,tid[top[x]],tid[x]);x=fa[top[x]];}else{t=0;query(1,1,n,tid[top[y]],tid[y]);y=fa[top[y]];}}if(dep[x]>dep[y]){t=1;query(1,1,n,tid[y],tid[x]);     }else{t=0;query(1,1,n,tid[x],tid[y]);}ull T0=(t0[1]&t1[0])|(~t0[1]&t0[0]);ull T1=(t1[1]&t1[0])|(~t1[1]&t0[0]);ull v=0,ans=0;for(int i=k;~i;i--){ull v1=v|(1ull<<i);if(v1<=z){if(T0&(1ull<<i)||!(T1&(1ull<<i)))ans|=T0&(1ull<<i);else{ans|=T1&(1ull<<i);v|=(1ull<<i);}}else{ans|=T0&(1ull<<i);}}return ans;
}
int main(){memset(head,cnt=-1,sizeof(head));n=read();m=read();k=read();k--;for(int i=1;i<=n;i++)opt[i]=read(),val[i]=read();for(int i=1;i<n;i++)addedge(read(),read());dfs1(1,1);dfs2(1,1);build(1,1,n);while(m--){int q=read(),x=read( ),y=read( );z=read( );if(q==1)  printf("%llu\n",ask(x,y));else{op=y;update(1,1,n,tid[x],z);}}return 0;
}

[bzoj 4811] 由乃的OJ(贪心 + 树链剖分)相关推荐

  1. BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)

    毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...

  2. P6805-[CEOI2020]春季大扫除【贪心,树链剖分,线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P6805 题目大意 给出nnn个点的一棵树,qqq次独立的询问.每次询问会在一些节点上新增一些子节点,然后你每次可以 ...

  3. bzoj 3626: [LNOI2014]LCA(离线差分+树链剖分)

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2885  Solved: 1133 [Submit][Sta ...

  4. UOJ #268 BZOJ 4732 [清华集训2016]数据交互 (树链剖分、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4732 (UOJ) http://uoj.ac/problem/268 题解 ...

  5. BZOJ 4679/Hdu5331 Simple Problem LCT or 树链剖分

    4679: Hdu5331 Simple Problem 题意: 考场上,看到这道题就让我想起BZOJ4712洪水.然后思路就被带着飞起了,完全没去考虑一条链的情况,于是GG. 解法:先考虑一条链的做 ...

  6. BZOJ 2243 染色(树链剖分好题)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 7971  Solved: 2990 [Submit][Stat ...

  7. BZOJ 4811 树链剖分+线段树

    思路: 感觉这题也可神了.. (还是我太弱) 首先发现每一位不会互相影响,可以把每一位分开考虑,然后用树链剖分或者LCT维护这个树 修改直接修改,询问的时候算出来每一位填0,1经过这条链的变换之后得到 ...

  8. BZOJ-4811: [Ynoi2017]由乃的OJ (树链剖分 线段树维护区间操作值 好题)

    4811: [Ynoi2017]由乃的OJ Time Limit: 6 Sec  Memory Limit: 256 MB Submit: 366  Solved: 118 [Submit][Stat ...

  9. BZOJ 2157 「国家集训队」旅游(树链剖分,线段树,边权转点权)【BZOJ计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2157 是 hydro 的 BZOJ ...

最新文章

  1. python简笔画绘制 数据驱动绘图_pytorch visdom可视化工具学习—2—详细使用-2-plotting绘图...
  2. oracle离线文档查dbms_Oracle的健康检查–dbms_hm的使用 | 学步园
  3. YBTOJ:向量问题(线段树分治、凸包)
  4. 班级日常分享,一天一瞬间
  5. 汇编语言-学习笔记(一)
  6. JAVA深入研究——Method的Invoke方法(转)
  7. obj模型 vue_Vue各种各样的模型库 Cornucopia 3D for Vue
  8. 【SSM项目实战】航班订票系统SpringMVC+MyBatis+LayUI
  9. L13:MySQL - 性能与SQL优化2
  10. dell灵越笔记本后盖怎么拆_如何拆卸Dell Inspiron 15 5570笔记本电脑并安装M.2 SSD
  11. msrcr(Multi-Scale Retinex with Color Restoration) 带色彩恢复的多尺度视网膜增强算法 整理
  12. QList使用注意(浅拷贝 深拷贝)
  13. Android——Hander+Service,实现后台长期周期性定时任务
  14. 天下文章一大抄看你会抄不会抄devGridView凭证金额录入(万仟百拾元)
  15. 康旅江湖,谁在编写琅琊榜
  16. ToolSettings app 实现系统本地升级
  17. 大白映射 宝马Esys编程设码映射、USB设备映射
  18. 40、100 个网络基础知识普及
  19. 【开源电机驱动】H 桥驱动-软件篇
  20. Vue选项式 API 的生命周期选项和组合式 API

热门文章

  1. 机器学习之模型——保存与加载
  2. react只停留在表层?五大知识点带你梳理进阶知识
  3. 平均成绩计算机控件,计算机技术基础(第十二章 文件 )
  4. [设计模式]单例模式(懒汉式,饿汉式)
  5. C++ struct实现顺序表
  6. D-query SPOJ - DQUERY(主席树求区间中不同的数的个数)
  7. linux常用命令 java,Java工程在Linux常用命令
  8. windows路由表 重启后就还原了_绕过Apple id并可以随意重启的终极方案来了 (Windows下操作)...
  9. wordList04
  10. linux6.5dns装什么,CentOS6.5安装DNS服务