bzoj4811
题解:
对于每一个节点,我们建立v0,v1
v0表示0进过会怎么样
v1表示1进过会怎么样
然后线段树合并
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
typedef unsigned long long ull;
ull a[N],zz,now,ans;
int n,m,k,op,xx,yy,Op[N],fi[N],ne[N*],v[N*],tot;
int size[N],fa[N],son[N],deep[N],rev[N],dfn[N],cnt,top[N];
struct Tree
{
ull v0,v1;Tree(){}
Tree(int op,ull x)
{
if (op==)v0=,v1=x;
else if (op==)v0=x,v1=~;
else v0=x,v1=(~)^x;
}
Tree(ull x,ull y){v0=x,v1=y;}
}trl[N*],trr[N*];
Tree operator+(Tree x,Tree y)
{
return Tree((x.v0&y.v1)|((~x.v0)&y.v0),(x.v1&y.v1)|((~x.v1)&y.v0));
}
void jb(int x,int y)
{
v[tot]=y;
ne[tot]=fi[x];
fi[x]=tot++;
}
void dfs1(int x)
{
size[x]=;
for (int i=fi[x];~i;i=ne[i])
if (v[i]!=fa[x])
{
fa[v[i]]=x;
deep[v[i]]=deep[x]+;
dfs1(v[i]);
size[x]+=size[v[i]];
if (size[v[i]]>size[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int tp)
{
rev[dfn[x]=++cnt]=x;
top[x]=tp;
if (son[x])dfs2(son[x],tp);
for (int i=fi[x];~i;i=ne[i])
if (v[i]!=fa[x]&&v[i]!=son[x])dfs2(v[i],v[i]);
}
void build(int l,int r,int pos)
{
if (l==r)
{
trl[pos]=trr[pos]=Tree(Op[rev[l]],a[rev[l]]);
return;
}
int mid=(l+r)>>;
build(l,mid,pos*);
build(mid+,r,pos*+);
trl[pos]=trl[pos*]+trl[pos*+];
trr[pos]=trr[pos*+]+trr[pos*];
}
void insert(int l,int r,int pos,int num)
{
if (l==r)
{
trl[pos]=trr[pos]=Tree(Op[rev[l]],a[rev[l]]);
return;
}
int mid=(l+r)>>;
if (mid<num)insert(mid+,r,pos*+,num);
else insert(l,mid,pos*,num);
trl[pos]=trl[pos*]+trl[pos*+];
trr[pos]=trr[pos*+]+trr[pos*];
}
Tree query(int l,int r,int pos,int L,int R,int f)
{
if (l>=L&&r<=R)return f?trr[pos]:trl[pos];
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
if (mid<L)return query(mid+,r,pos*+,L,R,f);
if (mid>=R)return query(l,mid,pos*,L,R,f);
if (!f)return query(l,mid,pos*,L,R,f)+query(mid+,r,pos*+,L,R,f);
return query(mid+,r,pos*+,L,R,f)+query(l,mid,pos*,L,R,f);
}
Tree solve(int x,int y)
{
Tree vx=Tree((int),0ull),vy=Tree((int),0ull);
int fx=top[x],fy=top[y];
while (fx!=fy)
if (deep[fx]>deep[fy])
{
vx=vx+query(,n,,dfn[fx],dfn[x],);
x=fa[fx];
fx=top[x];
}
else
{
vy=query(,n,,dfn[fy],dfn[y],)+vy;
y=fa[fy];
fy=top[y];
}
if (deep[x]>deep[y])return vx+query(,n,,dfn[y],dfn[x],)+vy;
return vx+query(,n,,dfn[x],dfn[y],)+vy;
}
int main()
{
memset(fi,-,sizeof(fi));
deep[]=;
scanf("%d%d%d",&n,&m,&k);
for (int i=;i<=n;i++)scanf("%d%llu",&Op[i],&a[i]);
for (int i=;i<n;i++)
{
scanf("%d%d",&xx,&yy);
jb(xx,yy);jb(yy,xx);
}
dfs1();dfs2(,);
build(,n,);
while (m--)
{
scanf("%d%d%d%llu",&op,&xx,&yy,&zz);
if (op==)Op[xx]=yy,a[xx]=zz,insert(,n,,dfn[xx]);
else
{
Tree t=solve(xx,yy);now=ans=;
for (int i=k-;~i;i--)
if (t.v0&(1ull<<i))ans+=1ull<<i;
else if (t.v1&(1ull<<i)&&now+(1ull<<i)<=zz)
{
now+=1ull<<i;
ans+=1ull<<i;
}
printf("%llu\n",ans);
}
}
return ;
}
bzoj4811的更多相关文章
- BZOJ4811 [Ynoi2017]由乃的OJ 树链剖分
原文链接http://www.cnblogs.com/zhouzhendong/p/8085286.html 题目传送门 - BZOJ4811 题意概括 是BZOJ3668长在树上并加上修改和区间询问 ...
- [BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)
起床困难综合症那题,只要从高往低贪心,每次暴力跑一边看这一位输入0和1分别得到什么结果即可. 放到序列上且带修改,只要对每位维护一个线段树,每个节点分别记录0和1从左往右和从右往左走完这段区间后变成的 ...
- BZOJ4811 [Ynoi2017]由乃的OJ
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 【bzoj4811】由乃的OJ
Portal --> bzoj4811 Solution 这题可以用树剖+线段树做也可以用LCT做,不过大体思路是一样的 (接下来先讲的是树剖+线段树的做法,再提LCT的做法) 首先位 ...
- BZOJ4811 Ynoi2017由乃的OJ(树链剖分+线段树)
先考虑NOI2014的水题,显然从高位到低位贪心,算一下该位取0和1分别得到什么即可. 加强这个水题,变成询问区间.那么线段树维护该位取0和1从左到右和从右到左走完这个节点表示的区间会变成什么即可,也 ...
- 【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树
[BZOJ4811][Ynoi2017]由乃的OJ Description 由乃正在做她的OJ.现在她在处理OJ上的用户排名问题.OJ上注册了n个用户,编号为1-",一开始他们按照编号排名. ...
- 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分+线段树区间合并
题解: 好像和noi那题并没有什么区别 只是加上了修改和变成树上 比较显然我们可以用树链剖分来维护
- Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心
传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...
- 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分/LCT+贪心
Description 给你一个有n个点的树,每个点的包括一个位运算opt和一个权值x,位运算有&,l,^三种,分别用1,2,3表示. 每次询问包含三个数x,y,z,初始选定一个数v.然后v依 ...
随机推荐
- docker 数据管理数据卷
1,数据卷 数据卷是一个可供容器使用特殊目录,他将主机操作系统目录直接映射容器 1,在容器内创建一个数据卷 在使用docker run命令的时候,使用-v标记就可以创建一个数据卷,多次重复使用-v可以 ...
- spring自定义事务同步器(二):借助redisson实现自己的同步器
1. 借助redis的java客户端redisson实现自己的事物同步器 @Override public void lockWithinCurrentTransaction(Object key) ...
- mysql 约束条件 auto_increment 自动增长目录
mysql 约束条件 auto_increment 自动增长 mysql 约束条件 auto_increment 自动增长起始值 布长 起始偏移量 mysql 约束条件 auto_increment ...
- mysql 数据操作 单表查询 练习
查出所有员工的名字,薪资,格式为 <名字:egon>,<薪资:3000> mysql> select concat('<姓名:',name,'>') as n ...
- 让Windows Server 2008 + IIS 7+ ASP.NET 支持10万并发请求 The serverRuntime@appConcurrentRequestLimit setting is being exceeded.
今天下午17点左右,博客园博客站点出现这样的错误信息: Error Summary: HTTP Error 503.2 - Service UnavailableThe serverRuntime@a ...
- 翻译:Addressing tiles: same tile bounds with different indexes
原文链接:http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/ Addressing tiles: same ...
- 翻译:Bing地图瓦片体系
Bing Maps Tile System Bing地图瓦片体系 原文链接:http://msdn.microsoft.com/en-us/library/bb259689.aspx Bing Map ...
- MySQL中特有的函数CONV函数
CONV函数:用于对数字进行转换,比如将十进制的数字转化成二进制,参数格式convert(N,frombse,tobase) 将数字N从frombase进制转化成tobase进制,并且以字符串的格式返 ...
- 文件名含中文的JavaWeb文件下载
在javaweb项目中实现文件下载,当文件名中包含中文文字时,需要进行如下的处理,才能在浏览器端正常显示中文文件名: response.setContentType("octets/stre ...
- 常用技巧之JS判断数组中某元素出现次数
先上代码:function arrCheck(arr){ var newArr = []; for(var i=0;i<arr.length;i++){ var temp=arr[i] ...