【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树
【BZOJ4811】[Ynoi2017]由乃的OJ
Description
Input
Output
Sample Input
1 7
2 6
3 7
3 6
3 1
1 2
2 3
3 4
1 5
1 1 4 7
1 1 3 5
2 1 1 3
2 3 3 3
1 1 3 2
Sample Output
1
5
题解:思路同BZOJ2908又是nand,不过本题nlog3n显然过不去,所以我们考虑优化我们的算法。
考虑能否不拆位,将所有位压成一个unsigned long long一起尽行计算。设l0表示一个所有位都是0的数从左往右经过这段区间会变成什么,l1表示一个所有位都是1的数从左往右经过这个点会变成什么,那么显然有:
l0[x]=(l0[lson]&l1[rson])|((~l0[lson])&l0[rson])
l1[x]=(l1[lson]&l1[rson])|((~l1[lson])&l0[rson])
r0,r1同理,然后就是nlog2n的了。
#include <cstdio>
#include <cstring>
#include <iostream>
#define lson x<<1
#define rson x<<1|1
using namespace std;
typedef unsigned long long ll;
const int maxn=100010;
int n,m,k,cnt;
ll msk;
ll l0[maxn<<2],l1[maxn<<2],r0[maxn<<2],r1[maxn<<2],v[maxn];
int to[maxn<<1],next[maxn<<1],head[maxn],dep[maxn],fa[maxn],top[maxn],son[maxn],siz[maxn],p[maxn],op[maxn],q[maxn];
int st[maxn];
void pushup(int x)
{
l0[x]=(l0[lson]&l1[rson])|((~l0[lson])&l0[rson]);
l1[x]=(l1[lson]&l1[rson])|((~l1[lson])&l0[rson]);
r0[x]=(r0[rson]&r1[lson])|((~r0[rson])&r0[lson]);
r1[x]=(r1[rson]&r1[lson])|((~r1[rson])&r0[lson]);
}
void build(int l,int r,int x)
{
if(l==r)
{
if(op[q[l]]==1) l1[x]=r1[x]=v[q[l]],l0[x]=r0[x]=0;
if(op[q[l]]==2) l1[x]=r1[x]=msk,l0[x]=r0[x]=v[q[l]];
if(op[q[l]]==3) l1[x]=r1[x]=v[q[l]]^msk,l0[x]=r0[x]=v[q[l]];
return ;
}
int mid=l+r>>1;
build(l,mid,lson),build(mid+1,r,rson);
pushup(x);
}
void updata(int l,int r,int x,int a,int op,ll val)
{
if(l==r)
{
if(op==1) l1[x]=r1[x]=val,l0[x]=r0[x]=0;
if(op==2) l1[x]=r1[x]=msk,l0[x]=r0[x]=val;
if(op==3) l1[x]=r1[x]=val^msk,l0[x]=r0[x]=val;
return ;
}
int mid=l+r>>1;
if(a<=mid) updata(l,mid,lson,a,op,val);
else updata(mid+1,r,rson,a,op,val);
pushup(x);
}
ll ql(int l,int r,int x,int a,int b,ll val)
{
if(a<=l&&r<=b) return (val&l1[x])|((~val)&l0[x]);
int mid=l+r>>1;
if(b<=mid) return ql(l,mid,lson,a,b,val);
if(a>mid) return ql(mid+1,r,rson,a,b,val);
return ql(mid+1,r,rson,a,b,ql(l,mid,lson,a,b,val));
}
ll qr(int l,int r,int x,int a,int b,ll val)
{
if(a<=l&&r<=b) return (val&r1[x])|((~val)&r0[x]);
int mid=l+r>>1;
if(b<=mid) return qr(l,mid,lson,a,b,val);
if(a>mid) return qr(mid+1,r,rson,a,b,val);
return qr(l,mid,lson,a,b,qr(mid+1,r,rson,a,b,val));
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i!=-1;i=next[i])
{
if(to[i]!=fa[x])
{
fa[to[i]]=x,dep[to[i]]=dep[x]+1,dfs1(to[i]),siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
}
}
void dfs2(int x,int tp)
{
top[x]=tp,p[x]=++p[0],q[p[0]]=x;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
}
void ask(int x,int y,ll mx)
{
ll ret=0,r0=0,r1=msk;
st[0]=0;
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]]) r0=qr(1,n,1,p[top[x]],p[x],r0),r1=qr(1,n,1,p[top[x]],p[x],r1),x=fa[top[x]];
else st[++st[0]]=y,y=fa[top[y]];
}
if(dep[x]>dep[y]) r0=qr(1,n,1,p[y],p[x],r0),r1=qr(1,n,1,p[y],p[x],r1);
else r0=ql(1,n,1,p[x],p[y],r0),r1=ql(1,n,1,p[x],p[y],r1);
for(int i=st[0];i;i--) y=st[i],r0=ql(1,n,1,p[top[y]],p[y],r0),r1=ql(1,n,1,p[top[y]],p[y],r1);
for(int i=k-1;~i;i--)
{
if(mx<(1ULL<<i)||(r0&(1ULL<<i))>=(r1&(1ULL<<i))) ret|=(r0&(1ULL<<i));
else ret|=(r1&(1ULL<<i)),mx-=(1ULL<<i);
}
printf("%llu\n",ret);
}
void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
inline ll rd()
{
ll ret=0; char gc=getchar();
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+(gc-'0'),gc=getchar();
return ret;
}
int main()
{
n=rd(),m=rd(),k=rd();
int i,a,b,d;
ll c;
for(i=0;i<k;i++) msk|=(1ULL<<i);
for(i=1;i<=n;i++) op[i]=rd(),v[i]=rd();
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
dep[1]=1,dfs1(1),dfs2(1,1);
build(1,n,1);
for(i=1;i<=m;i++)
{
d=rd(),a=rd(),b=rd(),c=rd();
if(d==1) ask(a,b,c);
else updata(1,n,1,p[a],b,c);
}
return 0;
}//5 5 3 1 7 2 6 3 7 3 6 3 1 1 2 2 3 3 4 1 5 1 1 4 7 1 1 3 5 2 1 1 3 2 3 3 3 1 1 3 2
【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 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
随机推荐
- 转 PV操作简单理解
传送门 PV操作简单理解 进程通常分为就绪.运行和阻塞三个工作状态.三种状态在某些条件下可以转换,三者之间的转换关系如下: 进程三个状态之间的转换就是靠PV操作来控制的.PV操作主要就是P操作.V操作 ...
- Android 禁止状态栏下拉status bar
如果你有这样的需求:用户进入你的app以后,所有的操作都是你的app中设定的,用户不可以拥有系统设置等行为的能力.然而,Android系统,可以通过从顶部往下拉,从而得到一个通知和快速系统设置的页面: ...
- CentOS找不到想要的镜像版本?
CentOS找不到想要的镜像版本? 情景: 当学习Linux时,一般教程不是最新的,教程里的CentOS版本也就不是最新的,这个时候, 在看着教程练习的时候就需要安装指定的版本,避免因为版本不同造成困 ...
- html --- rem
// rem (function(doc, win) { var docEle = doc.documentElement, evt = "onorientati ...
- Presto查询引擎简单分析
Hive查询流程分析 各个组件的作用 UI(user interface)(用户接口):提交数据操作的窗口Driver(引擎):负责接收数据操作,实现了会话句柄,并提供基于JDBC / ODBC的ex ...
- java多线程04----------final和static
final和static关键字 final关键字 1.final关键字在单线程中的特点: 1)final修饰的静态成员:必须在进行显示初始化或静态代码块赋值,并且仅能赋值一次. 2)final修饰的类 ...
- Maven的构建生命周期理解
以下引用官方的生命周期解释https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html: 一.构建生命 ...
- Eclipse工程中Java Build Path中的JDK版本和Java Compiler Compiler compliance level的区别(转)
在这里记录一下在eclipse中比较容易搞混淆和设置错误的地方.如下图所示的功能: 最精准的解释如下: Build Path是运行时环境 Compiler是编译时环境 假设,你的代码用到泛型,Bu ...
- 2008 SQL SERVER 用户 架构
2008 SQL SERVER 用户: SERVER用户与数据库用户 SERVER 与 数据库用户的映射,以使 登陆用户可访问数据库 架构等同于SCHEM (表空间),即表空间管理对象,建立层次对象关 ...
- JavaSE入门学习6:Java基础语法之运算符和语句(上)
继续接着上篇:JavaSE入门学习5:Java基础语法(一)来看Java的基础语法. 五运算符 运算符是一种"功能"符号,用以通知Java进行相关的运算.比方.我们须要将变量age ...