bzoj4811 [Ynoi2017]由乃的OJ 树链剖分+位运算
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4811
因为位运算的结果有可合并性,所以可以树链剖分,线段树维护;
细节很多,特别要注意从左往右运算和从右往左计算是不同的,在不同条件下一定要区分!!!
这篇博客写得很好(我就是模仿它写的):https://blog.csdn.net/a1799342217/article/details/78818480
代码如下:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- using namespace std;
- typedef unsigned long long ull;
- int const maxn=;
- int n,m,p,in[maxn],id[maxn],to[maxn],tp[maxn],head[maxn],ct,dep[maxn],fa[maxn],siz[maxn],tim;
- ull op[maxn][];
- struct N{
- int to,next;
- N(int t=,int n=):to(t),next(n) {}
- }edge[maxn<<];
- struct data{ull p0,p1;}tr[maxn<<],tl[maxn<<];
- struct T{int l,r;}t[maxn<<];
- void add(int x,int y){edge[++ct]=N(y,head[x]);head[x]=ct;}
- void dfs1(int x,int f)
- {
- fa[x]=f;dep[x]=dep[f]+;siz[x]=;
- for(int i=head[x];i;i=edge[i].next)
- {
- int u=edge[i].to;
- if(u==f)continue;
- dfs1(u,x);siz[x]+=siz[u];
- if(siz[u]>siz[to[x]])to[x]=u;
- }
- }
- void dfs2(int x)
- {
- in[id[x]=++tim]=x;
- if(to[x])tp[to[x]]=tp[x],dfs2(to[x]);
- for(int i=head[x];i;i=edge[i].next)
- {
- int u=edge[i].to;
- if(u!=fa[x]&&u!=to[x])tp[u]=u,dfs2(u);
- }
- }
- data update(ull op,ull w)
- {
- data ret;
- if(op==)ret.p0=(&w),ret.p1=((~)&w);
- if(op==)ret.p0=(|w),ret.p1=((~)|w);
- if(op==)ret.p0=(^w),ret.p1=((~)^w);
- return ret;
- }
- data pushup(data x,data y)
- {
- data ret;
- ret.p0=(x.p0&y.p1) | ((~x.p0)&y.p0);
- ret.p1=(x.p1&y.p1) | ((~x.p1)&y.p0);
- return ret;
- }
- void build(int x,int l,int r)
- {
- t[x].l=l;t[x].r=r;
- if(l==r)
- {
- tl[x]=tr[x]=update(op[in[l]][],op[in[l]][]);//in[l]而非x!
- return;
- }
- int mid=((l+r)>>);
- build(x<<,l,mid); build(x<<|,mid+,r);
- tl[x]=pushup(tl[x<<],tl[x<<|]);
- // tr[x]=pushup(tr[x<<1],tr[x<<1|1]);
- tr[x]=pushup(tr[x<<|],tr[x<<]);//!!!!!!!!!!
- }
- data sch(int x,int l,int r,int fl)
- {
- if(t[x].l>=l&&t[x].r<=r)
- return fl?tr[x]:tl[x];
- // int mid=((l+r)>>1);
- int mid=((t[x].l+t[x].r)>>);
- if(r<=mid)return sch(x<<,l,r,fl);
- else if(l>mid)return sch(x<<|,l,r,fl);
- else return pushup(sch((x<<)+fl,l,r,fl),sch((x<<|)-fl,l,r,fl));//从左往右或从右往左pushup有不同
- }
- data find(int x,int y)
- {
- data ans1=update(,),ans2=update(,);//ans1为x到lca,ans2为y到lca
- while(tp[x]!=tp[y])
- {
- // if(dep[x]>dep[y])
- if(dep[tp[x]]>dep[tp[y]])
- {
- ans1=pushup(ans1,sch(,id[tp[x]],id[x],));
- x=fa[tp[x]];
- }
- else
- {
- ans2=pushup(sch(,id[tp[y]],id[y],),ans2);
- y=fa[tp[y]];
- }
- }
- if(dep[x]<dep[y])return pushup(pushup(ans1,sch(,id[x],id[y],)),ans2);
- else return pushup(pushup(ans1,sch(,id[y],id[x],)),ans2);
- }
- void query(int x,int y,ull z)//ull
- {
- data ans=find(x,y);ull s=,ret=;
- for(int i=p-;i>=;i--)
- {
- if((1ull<<i)&ans.p0)ret+=(1ull<<i);
- else if(((1ull<<i)&ans.p1)&&s+(1ull<<i)<=z)
- ret+=(1ull<<i),s+=(1ull<<i);
- }
- printf("%llu\n",ret);
- }
- void modify(int x,int p,ull op,ull w)//ull
- {
- if(t[x].l==t[x].r)
- {
- tl[x]=tr[x]=update(op,w);
- return;//
- }
- int mid=((t[x].l+t[x].r)>>);
- if(p<=mid)modify(x<<,p,op,w);
- else modify(x<<|,p,op,w);
- tl[x]=pushup(tl[x<<],tl[x<<|]);
- // tr[x]=pushup(tr[x<<1],tr[x<<1|1]);
- tr[x]=pushup(tr[x<<|],tr[x<<]);
- }
- int main()
- {
- scanf("%d%d%d",&n,&m,&p);
- for(int i=;i<=n;i++)scanf("%llu%llu",&op[i][],&op[i][]);
- for(int i=,x,y;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
- dfs1(,);tp[]=;dfs2();build(,,n);
- for(int i=,q,x,y;i<=m;i++)
- {
- ull z;//
- scanf("%d%d%d%llu",&q,&x,&y,&z);
- if(q==)query(x,y,z);
- else modify(,id[x],y,z);//
- }
- return ;
- }
bzoj4811 [Ynoi2017]由乃的OJ 树链剖分+位运算的更多相关文章
- BZOJ4811 [Ynoi2017]由乃的OJ 树链剖分
原文链接http://www.cnblogs.com/zhouzhendong/p/8085286.html 题目传送门 - BZOJ4811 题意概括 是BZOJ3668长在树上并加上修改和区间询问 ...
- [BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)
起床困难综合症那题,只要从高往低贪心,每次暴力跑一边看这一位输入0和1分别得到什么结果即可. 放到序列上且带修改,只要对每位维护一个线段树,每个节点分别记录0和1从左往右和从右往左走完这段区间后变成的 ...
- Luogu3613 睡觉困难综合征/BZOJ4811 Ynoi2017 由乃的OJ 树链剖分、贪心
传送门 题意:给出一个$N$个点的树,树上每个点有一个位运算符号和一个数值.需要支持以下操作:修改一个点的位运算符号和数值,或者给出两个点$x,y$并给出一个上界$a$,可以选取一个$[0,a]$内的 ...
- bzoj4811 [Ynoi2017]由乃的OJ 树链剖分+贪心+二进制
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4811 题解 我现在为什么都写一题,调一天啊,马上真的退役不花一分钱了. 考虑这道题的弱化版 N ...
- 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分+线段树区间合并
题解: 好像和noi那题并没有什么区别 只是加上了修改和变成树上 比较显然我们可以用树链剖分来维护
- 【bzoj4811】[Ynoi2017]由乃的OJ 树链剖分/LCT+贪心
Description 给你一个有n个点的树,每个点的包括一个位运算opt和一个权值x,位运算有&,l,^三种,分别用1,2,3表示. 每次询问包含三个数x,y,z,初始选定一个数v.然后v依 ...
- 【BZOJ4811】[Ynoi2017]由乃的OJ 树链剖分+线段树
[BZOJ4811][Ynoi2017]由乃的OJ Description 由乃正在做她的OJ.现在她在处理OJ上的用户排名问题.OJ上注册了n个用户,编号为1-",一开始他们按照编号排名. ...
- [YNOI2017][bzoj4811][luogu3613] 由乃的OJ/睡觉困难综合症 [压位+树链剖分+线段树]
题面 BZOJ题面,比较不清晰 Luogu题面,写的比较清楚 思路 原题目 我们先看这道题的原题目NOI2014起床困难综合症 的确就是上树的带修改版本 那么我们先来解决这个原版的序列上单次询问 二进 ...
- BZOJ4811 [Ynoi2017]由乃的OJ
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
随机推荐
- UITableView点击背景
系统自定义的点击背景有时间觉得效果不好想换个 - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelect ...
- javascript 保护变量不被随意修改------优雅的编程
/* * 1.如果在renderTitle,renderContent里面,这样总数据谁都能修改,不安全 * 改进 * 1.规定一个专门修改数据的方法,如果想修改数据只能走这个方法 * * actio ...
- 【POJ2406】Power Strings(KMP,后缀数组)
题意: n<=1000000,cas较大 思路:这是一道论文题 后缀数组已弃疗,强行需要DC3构造,懒得(不会)写 ..]of longint; n,m,i,j,len,ans,st:longi ...
- mongodb 报错问题
系统不支持:Mongo 错误位置 FILE: C:\wamp64\www\frame\a_tp32\ThinkPHP\Library\Think\Db\Driver\Mongo.class.php L ...
- 动态规划:HDU 1114 Piggy-Bank
Problem Description Before ACM can do anything, a budget must be prepared and the necessary financia ...
- Two Sum(hashtable)
Given an array of integers, find two numbers such that they add up to a specific target number. The ...
- java-过滤器(Filter)
在javaweb开发中,项目中都会包含一些过滤器(Filter),主要用于web服务器对资源的管理控制,如静态资源文件.jsp页面访问等.我们可以使用过滤器实现一些特殊的功能,如常见的过滤敏感词汇(替 ...
- Spring的Web MVC框架
以下内容引用自http://wiki.jikexueyuan.com/project/spring/web-mvc-framework.html: Spring web MVC框架提供了模型-视图-控 ...
- Win7 SP1 安装SQL Server 2012时提示“此计算机上的操作系统不符合 SQL Server 2012的最低要求”
- 30分钟学会如何使用Shiro(转)
本文转自http://www.cnblogs.com/learnhow/p/5694876.html 感谢作者 本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jin ...