BZOJ4811 Ynoi2017由乃的OJ(树链剖分+线段树)
先考虑NOI2014的水题,显然从高位到低位贪心,算一下该位取0和1分别得到什么即可。
加强这个水题,变成询问区间。那么线段树维护该位取0和1从左到右和从右到左走完这个节点表示的区间会变成什么即可,也滋磁修改了。
然后上树,显然树剖即可。非常惨的变成了O(nklog2n)。压一下位就不惨了,变成O(n(k+log2n))。
树剖lca都能写挂调一天,不会熟练剖分,退役了。
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- #define ll unsigned long long
- #define N 100010
- char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
- int gcd(int n,int m){return m==?n:gcd(m,n%m);}
- ll read()
- {
- ll x=;char c=getchar();
- while (c<''||c>'') c=getchar();
- while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
- return x;
- }
- ll b[N],gor[N<<][],gol[N<<][],inf,I;
- int n,m,k,a[N],p[N],t,cnt;
- int id[N],dfn[N],top[N],fa[N],son[N],size[N],deep[N];
- int L[N<<],R[N<<];
- struct data{int to,nxt;
- }edge[N<<];
- struct data2{ll x,y;};
- void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
- void dfs(int k)
- {
- size[k]=;
- for (int i=p[k];i;i=edge[i].nxt)
- if (edge[i].to!=fa[k])
- {
- fa[edge[i].to]=k;
- deep[edge[i].to]=deep[k]+;
- dfs(edge[i].to);
- size[k]+=size[edge[i].to];
- if (size[edge[i].to]>size[son[k]]) son[k]=edge[i].to;
- }
- }
- void dfs2(int k,int from)
- {
- top[k]=from;dfn[k]=++cnt;id[cnt]=k;
- if (son[k]) dfs2(son[k],from);
- for (int i=p[k];i;i=edge[i].nxt)
- if (edge[i].to!=fa[k]&&edge[i].to!=son[k]) dfs2(edge[i].to,edge[i].to);
- }
- ll trans1(ll x,int op,ll y){if (op==) return x&y;if (op==) return x|y;return x^y;}
- ll trans(ll x,ll t0,ll t1){return (x&t1)|((~x)&t0);}
- void up(int k)
- {
- gor[k][]=trans(gor[k<<][],gor[k<<|][],gor[k<<|][]);
- gor[k][]=trans(gor[k<<][],gor[k<<|][],gor[k<<|][]);
- gol[k][]=trans(gol[k<<|][],gol[k<<][],gol[k<<][]);
- gol[k][]=trans(gol[k<<|][],gol[k<<][],gol[k<<][]);
- }
- void build(int k,int l,int r)
- {
- L[k]=l,R[k]=r;
- if (l==r) {gol[k][]=gor[k][]=trans1(,a[id[l]],b[id[l]]);gol[k][]=gor[k][]=trans1(inf,a[id[l]],b[id[l]]);return;}
- int mid=l+r>>;
- build(k<<,l,mid);
- build(k<<|,mid+,r);
- up(k);
- }
- void modify(int k,int x,int op,ll y)
- {
- if (L[k]==R[k]) {gol[k][]=gor[k][]=trans1(,op,y);gol[k][]=gor[k][]=trans1(inf,op,y);return;}
- int mid=L[k]+R[k]>>;
- if (x<=mid) modify(k<<,x,op,y);
- else modify(k<<|,x,op,y);
- up(k);
- }
- data2 queryl(int k,int l,int r)
- {
- if (L[k]==l&&R[k]==r) return (data2){gol[k][],gol[k][]};
- int mid=L[k]+R[k]>>;
- if (r<=mid) return queryl(k<<,l,r);
- else if (l>mid) return queryl(k<<|,l,r);
- else
- {
- data2 x=queryl(k<<|,mid+,r),y=queryl(k<<,l,mid);
- return (data2){trans(x.x,y.x,y.y),trans(x.y,y.x,y.y)};
- }
- }
- data2 queryr(int k,int l,int r)
- {
- if (L[k]==l&&R[k]==r) return (data2){gor[k][],gor[k][]};
- int mid=L[k]+R[k]>>;
- if (r<=mid) return queryr(k<<,l,r);
- else if (l>mid) return queryr(k<<|,l,r);
- else
- {
- data2 x=queryr(k<<,l,mid),y=queryr(k<<|,mid+,r);
- return (data2){trans(x.x,y.x,y.y),trans(x.y,y.x,y.y)};
- }
- }
- void solve(ll &t0,ll &t1,int x,int lca)
- {
- if (top[x]==top[lca])
- {
- data2 t=queryr(,dfn[lca],dfn[x]);
- t0=trans(t0,t.x,t.y),t1=trans(t1,t.x,t.y);
- return;
- }
- solve(t0,t1,fa[top[x]],lca);
- data2 t=queryr(,dfn[top[x]],dfn[x]);
- t0=trans(t0,t.x,t.y),t1=trans(t1,t.x,t.y);
- }
- ll jump_query(int x,int y,ll z)
- {
- ll t0=,t1=inf;data2 t;int lca=,P=x,Q=y;
- while (top[P]!=top[Q])
- {
- if (deep[top[P]]<deep[top[Q]]) swap(P,Q);
- P=fa[top[P]];
- }
- if (deep[P]<deep[Q]) swap(P,Q);
- lca=Q;
- while (top[x]!=top[lca])
- {
- t=queryl(,dfn[top[x]],dfn[x]);
- t0=trans(t0,t.x,t.y),t1=trans(t1,t.x,t.y);
- x=fa[top[x]];
- }
- if (lca!=x)
- {
- for (int i=p[lca];i;i=edge[i].nxt)
- if (dfn[edge[i].to]>dfn[lca]&&dfn[edge[i].to]<=dfn[x]) {t=queryl(,dfn[edge[i].to],dfn[x]);break;}
- t0=trans(t0,t.x,t.y),t1=trans(t1,t.x,t.y);
- }
- solve(t0,t1,y,lca);
- ll s=,c=;
- for (int i=k-;~i;i--)
- if (t0&(I<<i)) s+=I<<i;
- else if ((t1&(I<<i))&&c+(I<<i)<=z) c+=I<<i,s+=I<<i;
- return s;
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("bzoj4811.in","r",stdin);
- freopen("bzoj4811.out","w",stdout);
- const char LL[]="%I64d\n";
- #else
- const char LL[]="%lld\n";
- #endif
- n=read(),m=read(),k=read();inf=I=;for (int i=;i<=k;i++) inf<<=;inf--;
- for (int i=;i<=n;i++) a[i]=read(),b[i]=read();
- for (int i=;i<n;i++)
- {
- int x=read(),y=read();
- addedge(x,y),addedge(y,x);
- }
- dfs();
- dfs2(,);
- build(,,n);
- while (m--)
- {
- int op=read(),x=read(),y=read();ll z=read();
- if (op==) printf("%llu\n",jump_query(x,y,z));
- else modify(,dfn[x],y,z);
- }
- return ;
- }
BZOJ4811 Ynoi2017由乃的OJ(树链剖分+线段树)的更多相关文章
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
随机推荐
- WPF 应用程序资源、内容和数据文件
MSDN相关介绍: http://msdn.microsoft.com/zh-cn/library/aa970494(v=vs.100).aspx 内容文件(Content Files)内容文件简单的 ...
- Java:二进制(原码、反码、补码)与位运算
一.二进制(原码.反码.补码) 二进制的最高位是符号位(“0”代表正数,“1”代表负数): Java中没有无符号数: 计算机以整数的补码进行运算: 1. 原码:将一个整数转换成二进制表示 以 int ...
- 解决replace格式替换后光标定位问题
场景:格式化银行卡444格式 手机号344格式 身份证号684格式 校验数据格式,replace后光标定位错乱 或光标一直定位在最后 解决,只针对input,代码用的vue: 获取光标位置: getC ...
- 代码重复率检查工具jsinspect
检查重复代码,去掉冗余代码. 安装: npm install -g jsinspect 用法:jsinspect [options] <paths ...> 检测复制粘贴和结构类似的Jav ...
- 「专题训练」Air Raid(HDU-1151)
题目 在一个城市里有\(n\)个地点和\(k\)条道路,道路是无环的(也就是说一定可以二分染色--回路长度为偶数0),现在伞兵需要去n个地点视察,只能沿着路的方向走,问最少需要多少伞兵. 分析 这是什 ...
- 通过 Python_Faker 生成测试数据
通过 Python_Faker 生成测试数据 一.介绍 在软件需求.开发.测试过程中,有时候需要使用一些测试数据,针对这种情况,我们一般要么使用已有的系统数据,你不可能通过手工来生成(最傻的方法)可能 ...
- C#冒泡排序法及优化
冒泡排序法及优化: static void Main(string[] args) { , , , , , }; ; //冒泡排序法 ; i < sums.Length - ; i++) //总 ...
- MVC数据的注册及验证简单总结
一.注解 注解是一种通用机制,可以用来向框架注入元数据,同时,框架不只驱动元数据的验证,还可以在生成显示和编辑模型的HTML标记时使用元数据. 二.验证注册的使用 1.Require:属性为Null或 ...
- [Clr via C#读书笔记]Cp10属性
Cp10属性 属性的本质就是方法,只是看起来像字段罢了: 无参属性 就是一般属性: 字段一般要private,然后通过设置访问方法-访问器来访问:属性是方法语法变种:getset不一定要访问支持字段: ...
- Hexo 博客 之 腾讯云部署过程
写在前面 Hexo 博客搭好了有差不多两周时间了,这期间走了很多弯路,跳了很多坑.一些坑自己 bing 到了答案,找到了解决方法,一些坑则是自己摸索出来的解决方法.现在准备写几篇关于搭建流程.搭建过程 ...