原文链接http://www.cnblogs.com/zhouzhendong/p/8085286.html


题目传送门 - BZOJ4811


题意概括

  是BZOJ3668长在树上并加上修改和区间询问。

  一棵树,n个节点,每一个节点有一个位运算符和一个运算数。

  现在要你支持两种操作:

  1. 单点修改。

  2. 现在你有一个数字v,让他从x走到y,每到达一个节点进行相应的运算。v在0~z之间,让你使得运算结果最大,问v为何值。


题解

  我们考虑树链剖分+线段树。

  假设某一位为0或者1,那么经过一定的操作之后也是0或1.

  那么,如果只有一位,那么两段就可以轻松合并了。

  k位也是一样,我们只需要用一堆奇怪的位运算就可以了,详见代码。

  要维护正的和反的。然后好像没什么要说的了。


代码

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef unsigned long long ULL;
const int N=100005;
struct Gragh{
int cnt,y[N*2],nxt[N*2],fst[N];
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void add(int a,int b){
y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
}
}g;
int n,m,k,op[N];
int fa[N],son[N],size[N],depth[N],top[N],p[N],ap[N],cnp=0;
ULL Mod,val[N],n0=0,n1=~0;
void Get_Gen_Info(int rt,int pre,int d){
size[rt]=1,son[rt]=-1,fa[rt]=pre,depth[rt]=d;
for (int i=g.fst[rt];i;i=g.nxt[i])
if (g.y[i]!=pre){
int s=g.y[i];
Get_Gen_Info(s,rt,d+1);
size[rt]+=size[s];
if (son[rt]==-1||size[s]>size[son[rt]])
son[rt]=s;
}
}
void Get_Top(int rt,int tp){
top[rt]=tp;
ap[p[rt]=++cnp]=rt;
if (!~son[rt])
return;
Get_Top(son[rt],tp);
for (int i=g.fst[rt];i;i=g.nxt[i]){
int s=g.y[i];
if (s!=fa[rt]&&s!=son[rt])
Get_Top(s,s);
}
}
struct STree{
ULL L0,R0,L1,R1;
STree (){}
STree (int x){L0=R0=0,L1=R1=-1;}
STree (ULL a,ULL b,ULL c,ULL d){L0=a,R0=b,L1=c,R1=d;}
void rev(){swap(L0,R0),swap(L1,R1);}
void suit(){L0&=(Mod-1),L1&=(Mod-1),R0&=(Mod-1),R1&=(Mod-1);}
}t[N*4];
STree operator + (STree a,STree b){
STree ans;
ans.L0=((~a.L0)&b.L0)|(a.L0&b.L1);
ans.L1=((~a.L1)&b.L0)|(a.L1&b.L1);
ans.R0=((~b.R0)&a.R0)|(b.R0&a.R1);
ans.R1=((~b.R1)&a.R0)|(b.R1&a.R1);
return ans;
}
void build(int rt,int L,int R){
if (L==R){
int o=op[ap[L]];
ULL v=val[ap[L]];
if (o==1)t[rt].L0=t[rt].R0=n0&v,t[rt].L1=t[rt].R1=n1&v;
if (o==2)t[rt].L0=t[rt].R0=n0|v,t[rt].L1=t[rt].R1=n1|v;
if (o==3)t[rt].L0=t[rt].R0=n0^v,t[rt].L1=t[rt].R1=n1^v;
return;
}
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
build(ls,L,mid);
build(rs,mid+1,R);
t[rt]=t[ls]+t[rs];
}
void change(int rt,int L,int R,int pos,int o,ULL v){
if (L==R){
if (o==1)t[rt].L0=t[rt].R0=n0&v,t[rt].L1=t[rt].R1=n1&v;
if (o==2)t[rt].L0=t[rt].R0=n0|v,t[rt].L1=t[rt].R1=n1|v;
if (o==3)t[rt].L0=t[rt].R0=n0^v,t[rt].L1=t[rt].R1=n1^v;
return;
}
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
if (pos<=mid)
change(ls,L,mid,pos,o,v);
else
change(rs,mid+1,R,pos,o,v);
t[rt]=t[ls]+t[rs];
}
STree query(int rt,int L,int R,int xL,int xR){
if (R<xL||L>xR)
return STree(0);
if (xL<=L&&R<=xR)
return t[rt];
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
return query(ls,L,mid,xL,xR)+query(rs,mid+1,R,xL,xR);
}
ULL Tquery(int a,int b,ULL z){
int f1=top[a],f2=top[b],rev=0;
STree ansa(0),ansb(0);
while (f1!=f2){
if (depth[f1]<depth[f2])
swap(f1,f2),swap(a,b),swap(ansa,ansb),rev^=1;
ansa=query(1,1,n,p[f1],p[a])+ansa;
a=fa[f1],f1=top[a];
}
if (depth[a]>depth[b])
swap(a,b),swap(ansa,ansb),rev^=1;
ansa.rev();
STree ans=ansa+query(1,1,n,p[a],p[b])+ansb;
if (rev)
ans.rev();
ULL ansv=0;
// ans.suit();
for (int i=k;~i;i--){
if (ans.L0&(1ULL<<i))
ansv|=1ULL<<i;
else if (z>=(1ULL<<i)&&(ans.L1&(1ULL<<i)))
ansv|=1ULL<<i,z-=1ULL<<i;
}
return ansv;
}
int main(){
g.clear();
scanf("%d%d%d",&n,&m,&k);
for (int i=1;i<=n;i++)
scanf("%d%llu",&op[i],&val[i]);
Mod=1ULL<<k;
for (int i=1,a,b;i<n;i++){
scanf("%d%d",&a,&b);
g.add(a,b),g.add(b,a);
}
Get_Gen_Info(1,0,0);
Get_Top(1,1);
build(1,1,n);
for (int i=1;i<=m;i++){
int op,x,y;
ULL z;
scanf("%d%d%d%llu",&op,&x,&y,&z);
if (op==1)
printf("%llu\n",Tquery(x,y,z));
else
change(1,1,n,p[x],y,z);
}
return 0;
}

  

BZOJ4811 [Ynoi2017]由乃的OJ 树链剖分的更多相关文章

  1. [BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)

    起床困难综合症那题,只要从高往低贪心,每次暴力跑一边看这一位输入0和1分别得到什么结果即可. 放到序列上且带修改,只要对每位维护一个线段树,每个节点分别记录0和1从左往右和从右往左走完这段区间后变成的 ...

  2. Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心

    传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...

  3. bzoj4811 [Ynoi2017]由乃的OJ 树链剖分+位运算

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4811 因为位运算的结果有可合并性,所以可以树链剖分,线段树维护: 细节很多,特别要注意从左往 ...

  4. bzoj4811 [Ynoi2017]由乃的OJ 树链剖分+贪心+二进制

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4811 题解 我现在为什么都写一题,调一天啊,马上真的退役不花一分钱了. 考虑这道题的弱化版 N ...

  5. 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分+线段树区间合并

    题解: 好像和noi那题并没有什么区别 只是加上了修改和变成树上 比较显然我们可以用树链剖分来维护

  6. 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分/LCT+贪心

    Description 给你一个有n个点的树,每个点的包括一个位运算opt和一个权值x,位运算有&,l,^三种,分别用1,2,3表示. 每次询问包含三个数x,y,z,初始选定一个数v.然后v依 ...

  7. 【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树

    [BZOJ4811][Ynoi2017]由乃的OJ Description 由乃正在做她的OJ.现在她在处理OJ上的用户排名问题.OJ上注册了n个用户,编号为1-",一开始他们按照编号排名. ...

  8. [YNOI2017][bzoj4811][luogu3613] 由乃的OJ/睡觉困难综合症 [压位+树链剖分+线段树]

    题面 BZOJ题面,比较不清晰 Luogu题面,写的比较清楚 思路 原题目 我们先看这道题的原题目NOI2014起床困难综合症 的确就是上树的带修改版本 那么我们先来解决这个原版的序列上单次询问 二进 ...

  9. BZOJ4811 [Ynoi2017]由乃的OJ

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

随机推荐

  1. ASP.NET提供三种主要形式的缓存

    ASP.NET提供三种主要形式的缓存:页面级输出缓存.用户控件级输出缓存(或称为片段缓存)和缓存API.

  2. jenkins每次构建前删除工作目录操作

    背景: 想在拉取代码前,删除代码,结果百度白天找到答案,mark下 需要安装Workspace Cleanup Plugin插件, 再看创建任务项,勾选即可实现

  3. Confluence 6 附件存储选项

    在早期的 Confluence 版本中,我们允许存储附件到 WebDav 或者 Confluence 数据库中.针对新的 Confluence 安装,我们不再支持这 2 种存储了. 本地文件系统 在默 ...

  4. Confluence 6 为空白空间编辑默认主页

    希望编辑默认(空白)空间内容模板: 在屏幕的右上角单击 控制台按钮 ,然后选择 General Configuration 链接. 在左侧的面板中选择 全局模板和蓝图(Global Templates ...

  5. 动态获取后台传过来的值作为select选项

    问题描述:点击左侧菜单项,进入对应的具体页面a.html,页面上方有个select框,点击框后,会浮现选择项. 解决思路:对左侧菜单项添加一个onclick事件,进入后台做具体的查询,将查询到的lis ...

  6. Python关于类的实操

    实操一:总结 1.什么是绑定到对象的方法,如何定义,如何调用,给谁用?有什么特性? 2.什么是绑定到类的方法,如何定义,如何调用,给谁用?有什么特性? 3.什么是解除绑定的函数,如何定义,如何调用,给 ...

  7. ESD选型指南

    信息来自网络,可能有误,希望指正! 一.ESD工作原理 ESD静电保护元件,又称静电抑制二极管.ESD是多个TVS晶粒或二极管采用不同的布局做成具有特定功能的多路或单路ESD保护器件,主要应用于各类通 ...

  8. python Com接口测试

    import comtypes.client as cc import comtypes tlb_id = comtypes.GUID("{D85C6069-D628-4276-93C3-9 ...

  9. 装饰器实现session登陆 验证功能

    装饰器 登陆验证功能 1.装饰器模板 from django.shortcuts import render, redirect, HttpResponse from django.conf impo ...

  10. Asp.Net MVC Ajax轮训解决Session失效时间

    这种方法不是太好,对服务器得压力大,由于系统是内部人员使用,业务有比较复杂,所以有些值得需要Session去保存,但是,Session有失效时间. 代码如下: $(function () { func ...