起床困难综合症那题,只要从高往低贪心,每次暴力跑一边看这一位输入0和1分别得到什么结果即可。

放到序列上且带修改,只要对每位维护一个线段树,每个节点分别记录0和1从左往右和从右往左走完这段区间后变成的数即可。

放到树上,只要树链剖分即可。但这里有一个很大的常数k,实际上我们只需要一个数就可以记录64个二进制位的信息,于是复杂度$O(n\log^2 n)$

小错误毁一生。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #define ls (x<<1)
  6 #define rs (ls|1)
  7 #define lson ls,L,mid
  8 #define rson rs,mid+1,R
  9 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 10 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
 11 typedef unsigned long long ll;
 12 using namespace std;
 13
 14 const int N=100010;
 15 ll z,I=1;
 16 int n,m,k,u,v,x,y,op,cnt,tim,pos[N],sz[N],dep[N],son[N],fa[N],dfn[N],top[N];
 17 int h[N],to[N<<1],nxt[N<<1];
 18 struct P{ int op; ll x; }p[N];
 19 struct D{ ll s0,s1; }v1[N<<2],v2[N<<2];
 20 struct S{ int l,r; }lp[N],rp[N];
 21
 22 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
 23
 24 void work(int x,P p){
 25     if (p.op==1) v1[x]=v2[x]=(D){0,p.x};
 26     if (p.op==2) v1[x]=v2[x]=(D){p.x,-1};
 27     if (p.op==3) v1[x]=v2[x]=(D){p.x,p.x^(-1)};
 28 }
 29
 30 D operator +(D a,D b){ return (D){((~a.s0)&b.s0)|(a.s0&b.s1),((~a.s1)&b.s0)|(a.s1&b.s1)}; }
 31 void upd(int x){ v1[x]=v1[ls]+v1[rs]; v2[x]=v2[rs]+v2[ls]; }
 32
 33 void dfs(int x){
 34     sz[x]=1; dep[x]=dep[fa[x]]+1;
 35     For(i,x) if ((k=to[i])!=fa[x]){
 36         fa[k]=x; dfs(k); sz[x]+=sz[k];
 37         if (sz[k]>sz[son[x]]) son[x]=k;
 38     }
 39 }
 40
 41 void dfs2(int x,int tp){
 42     top[x]=tp; dfn[x]=++tim; pos[tim]=x;
 43     if (son[x]) dfs2(son[x],tp);
 44     For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k);
 45 }
 46
 47 void build(int x,int L,int R){
 48     if (L==R){ work(x,p[pos[L]]); return; }
 49     int mid=(L+R)>>1;
 50     build(lson); build(rson); upd(x);
 51 }
 52
 53 void mdf(int x,int L,int R,int pos,P p){
 54     if (L==R){ work(x,p); return; }
 55     int mid=(L+R)>>1;
 56     if (pos<=mid) mdf(lson,pos,p); else mdf(rson,pos,p);
 57     upd(x);
 58 }
 59
 60 D que(int x,int L,int R,int l,int r,int k){
 61     if (L==l && r==R) return (k==1) ? v1[x] : v2[x];
 62     int mid=(L+R)>>1;
 63     if (r<=mid) return que(lson,l,r,k);
 64     else if (l>mid) return que(rson,l,r,k);
 65         else{
 66             D a=que(lson,l,mid,k),b=que(rson,mid+1,r,k);
 67             return (k==1) ? a+b : b+a;
 68         }
 69 }
 70
 71 void solve(int x,int y,ll z){
 72     int ld=0,rd=0,rev=0;
 73     S *L=lp,*R=rp;
 74     for (; top[x]!=top[y]; x=fa[top[x]]){
 75         if (dep[top[x]]<dep[top[y]]) rev^=1,swap(x,y),swap(ld,rd),swap(L,R);
 76         L[++ld]=(S){dfn[top[x]],dfn[x]};
 77     }
 78     if (dep[x]<dep[y]) rev^=1,swap(x,y),swap(ld,rd),swap(L,R);
 79     L[++ld]=(S){dfn[y],dfn[x]};
 80     if (rev) swap(ld,rd),swap(L,R);
 81     D res=(D){0,-1};
 82     rep(i,1,ld) res=res+que(1,1,n,L[i].l,L[i].r,2);
 83     for (int i=rd; i; i--) res=res+que(1,1,n,R[i].l,R[i].r,1);
 84     ll s=0,c=0;
 85     for (int i=k-1; ~i; i--)
 86         if (res.s0&(I<<i)) s+=I<<i;
 87             else if ((res.s1&(I<<i)) && c+(I<<i)<=z) c+=I<<i,s+=I<<i;
 88     printf("%llu\n",s);
 89 }
 90
 91 int main(){
 92     freopen("bzoj4811.in","r",stdin);
 93     freopen("bzoj4811.out","w",stdout);
 94     scanf("%d%d%d",&n,&m,&k);
 95     rep(i,1,n) scanf("%d%llu",&p[i].op,&p[i].x);
 96     rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
 97     dfs(1); dfs2(1,1); build(1,1,n);
 98     rep(i,1,m){
 99         scanf("%d%d%d%llu",&op,&x,&y,&z);
100         if (op==1) solve(x,y,z); else mdf(1,1,n,dfn[x],(P){y,z});
101     }
102     return 0;
103 }

转载于:https://www.cnblogs.com/HocRiser/p/10129342.html

[BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)相关推荐

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  2. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  3. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  4. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  5. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...

  6. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  7. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  8. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  9. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  10. YbtOJ-染色计划【树链剖分,线段树,tarjan】

    正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai​,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...

最新文章

  1. 拆解交易系统--如何做好稳定性
  2. “大型票务系统”和“实物电商系统”的数据库选型
  3. AttributeError: ‘Model‘ object has no attribute ‘_get_distribution_strategy
  4. OpenHarmony和HarmonyOS有什么区别?这篇文章讲清楚了
  5. CentOS7部署(Mysql) MariaDB Galera Cluster 10.1记录
  6. android view 存值,使用ViewModel保存数据
  7. IPTV Checker(直播源自动检测工具)
  8. android 阅读器字体,为 Android 换上任意喜欢的字体,你可以试试这个 Magisk 模块...
  9. 计算机网络 全章节思维导图
  10. [4G5G专题-50]:物理层-数字波束赋型Beamforming及其数学原理
  11. 用GNS3制作路由交换网络拓扑图
  12. vue实现带图片的标题栏
  13. FLINK 极客时间
  14. 在浏览器中嵌入播放器
  15. 爬虫(一):用python爬取亚马逊所有家具种类前100名的商品信息(上)
  16. A Sample Crash Log
  17. 快速排序算法(图解+代码)
  18. 2022-2028年中国渗滤液行业市场运行态势及发展战略研究报告
  19. echarts lengend格式化和换行
  20. Excel函数--SUM计算累计销量

热门文章

  1. POJ2955Brackets——dp
  2. C++ 之父即将开始直播,请就位!
  3. bzoj3555 企鹅QQ
  4. 识别出脸部以及给脸部打马赛克
  5. Visual C++ 2008入门经典 第二十一章更新数据源
  6. 评:我从编程中悟出八个字(不算原创,不过希望让大家能看看)
  7. C中的位域与大小端问题
  8. 5种方式将机器学习带到Java、Python以及Go等编程语言
  9. Ubuntu16.04安装最新版nodejs
  10. L1-014. 简单题-PAT团体程序设计天梯赛GPLT