先考虑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(树链剖分+线段树)的更多相关文章

  1. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

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

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

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

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

  4. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  5. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  6. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  7. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  8. 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 ...

  9. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

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

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

随机推荐

  1. CLR via C#读书笔记二:类型基础

    1.CLR允许将对象转换为它的(实际)类型或者它的任何基类型. 2.is操作符检测对象是否兼容于指定类型,is操作符永远不抛出异常. 3.as操作符返回对同一个对象的非null引用.如果对象不兼容,a ...

  2. 安卓app连接CC2541-手机休眠后唤醒,通信不再成功

    1. 现在遇到的问题,手机进入休眠状态后唤醒,APP软件和CC2541的通信不正常了,但是CC2541依然检测到时连接状态.如何解决这个问题?手机唤醒之后会重新创建活动? 2.Wakelock 锁机制 ...

  3. Unity Container中的几种注册方式与示例

    1.实例注册 最简单的注册方式就是实例注册,Unity 容器负责维护对一个类型的单例引用,比如: 有如下的实际类型: namespace ConsoleSample { public class Sa ...

  4. Oracle锁表处理

    最近系统连续出现好几次锁表,昨晚又发生一次锁表,11点钟跑到客户现场,进过跟踪发现导致这次锁表的机器和上一次是同一台,花了近半小时解锁.之后到科室找到那台机器看看情况,发现那台机器速度超慢,保存一份病 ...

  5. Java基础知识总结一

    1.何为编程? 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路.方法.和手段通过计算机能够理解 ...

  6. 微信小程序如何性能测试?

    背景: 微信小程序作为手机页面的一种,相比传统的网站和应用来说存在比较特殊的地方: 1.  开发者往往对程序做了限制,只能通过微信客户端访问 2.  通过微信的Oauth进行认证 这样往往会导致我们的 ...

  7. 第三模块:面向对象&网络编程基础 第4章 FTP项目作业讲解

    01-FTP项目需求 02-FTP项目框架搭建 03-FTP项目用户认证 04--FTP项目制定标准定长消息头 05-FTP项目下载功能开发 06-FTP项目下载功能开发2 07-FTP项目ls文件列 ...

  8. python程序设计——文件操作

    分类 1.文本文件 存储常规字符串,由若干文本行组成,每行以换行符'\n'结尾 2.二进制文件 把对象以字节串存储,常见的图形图像.可执行文件.数据库文件office文档等 #创建文件 >> ...

  9. OpenMPI运行问题:enough slots available in the system

    版本: Open MPI 3.0.1 编译好可执行的C语言程序后,使用 mpirun -np 3 Test 命令,发现没有正常运行,而是报错: There are not enough slots a ...

  10. 深入理解eos账户体系 active和action

    在eos中,账户是一个非常重要的概念. 账户分为两部分组成 一种是active 一种是action. 智能合约本质上来讲就是一个action加上一个回馈脚本程序.任何智能合约都有这俩个部分组成. 那么 ...