[BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)
起床困难综合症那题,只要从高往低贪心,每次暴力跑一边看这一位输入0和1分别得到什么结果即可。
放到序列上且带修改,只要对每位维护一个线段树,每个节点分别记录0和1从左往右和从右往左走完这段区间后变成的数即可。
放到树上,只要树链剖分即可。但这里有一个很大的常数k,实际上我们只需要一个数就可以记录64个二进制位的信息,于是复杂度$O(n\log^2 n)$
小错误毁一生。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ls (x<<1)
#define rs (ls|1)
#define lson ls,L,mid
#define rson rs,mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
typedef unsigned long long ll;
using namespace std; const int N=;
ll z,I=;
int n,m,k,u,v,x,y,op,cnt,tim,pos[N],sz[N],dep[N],son[N],fa[N],dfn[N],top[N];
int h[N],to[N<<],nxt[N<<];
struct P{ int op; ll x; }p[N];
struct D{ ll s0,s1; }v1[N<<],v2[N<<];
struct S{ int l,r; }lp[N],rp[N]; void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } void work(int x,P p){
if (p.op==) v1[x]=v2[x]=(D){,p.x};
if (p.op==) v1[x]=v2[x]=(D){p.x,-};
if (p.op==) v1[x]=v2[x]=(D){p.x,p.x^(-)};
} D operator +(D a,D b){ return (D){((~a.s0)&b.s0)|(a.s0&b.s1),((~a.s1)&b.s0)|(a.s1&b.s1)}; }
void upd(int x){ v1[x]=v1[ls]+v1[rs]; v2[x]=v2[rs]+v2[ls]; } void dfs(int x){
sz[x]=; dep[x]=dep[fa[x]]+;
For(i,x) if ((k=to[i])!=fa[x]){
fa[k]=x; dfs(k); sz[x]+=sz[k];
if (sz[k]>sz[son[x]]) son[x]=k;
}
} void dfs2(int x,int tp){
top[x]=tp; dfn[x]=++tim; pos[tim]=x;
if (son[x]) dfs2(son[x],tp);
For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k);
} void build(int x,int L,int R){
if (L==R){ work(x,p[pos[L]]); return; }
int mid=(L+R)>>;
build(lson); build(rson); upd(x);
} void mdf(int x,int L,int R,int pos,P p){
if (L==R){ work(x,p); return; }
int mid=(L+R)>>;
if (pos<=mid) mdf(lson,pos,p); else mdf(rson,pos,p);
upd(x);
} D que(int x,int L,int R,int l,int r,int k){
if (L==l && r==R) return (k==) ? v1[x] : v2[x];
int mid=(L+R)>>;
if (r<=mid) return que(lson,l,r,k);
else if (l>mid) return que(rson,l,r,k);
else{
D a=que(lson,l,mid,k),b=que(rson,mid+,r,k);
return (k==) ? a+b : b+a;
}
} void solve(int x,int y,ll z){
int ld=,rd=,rev=;
S *L=lp,*R=rp;
for (; top[x]!=top[y]; x=fa[top[x]]){
if (dep[top[x]]<dep[top[y]]) rev^=,swap(x,y),swap(ld,rd),swap(L,R);
L[++ld]=(S){dfn[top[x]],dfn[x]};
}
if (dep[x]<dep[y]) rev^=,swap(x,y),swap(ld,rd),swap(L,R);
L[++ld]=(S){dfn[y],dfn[x]};
if (rev) swap(ld,rd),swap(L,R);
D res=(D){,-};
rep(i,,ld) res=res+que(,,n,L[i].l,L[i].r,);
for (int i=rd; i; i--) res=res+que(,,n,R[i].l,R[i].r,);
ll s=,c=;
for (int i=k-; ~i; i--)
if (res.s0&(I<<i)) s+=I<<i;
else if ((res.s1&(I<<i)) && c+(I<<i)<=z) c+=I<<i,s+=I<<i;
printf("%llu\n",s);
} int main(){
freopen("bzoj4811.in","r",stdin);
freopen("bzoj4811.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
rep(i,,n) scanf("%d%llu",&p[i].op,&p[i].x);
rep(i,,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
dfs(); dfs2(,); build(,,n);
rep(i,,m){
scanf("%d%d%d%llu",&op,&x,&y,&z);
if (op==) solve(x,y,z); else mdf(,,n,dfn[x],(P){y,z});
}
return ;
}
[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 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
随机推荐
- asp.net 调用post方法并获取返回值
/// <summary> /// http协议 post数据 接受返回结果 /// </summary> /// <param ...
- 【译】第十二篇 SQL Server代理多服务器管理
本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...
- css3兼容性问题归纳
Android2.3的overflow问题 在android2.3及以下系统版本的浏览器不支持overflow:scroll / auto,即在页面元素里面的内容如果超过了父元素或祖先元素的高度是无法 ...
- 使用转义防御XSS
使用转义防御XSS 在输出的时候防御XSS即对用户输入进行转义,XSS的问题本质上还是代码注入,HTML或者javascript的代码注入,即混淆了用户输入的数据和代码.而解决这个问题,就需要根据用户 ...
- 使用纯注解与配置类开发springMVC项目,去掉xml配置
最近拜读了杨开振老师的书,深入浅出springBoot2.x,挖掘了很多以前被忽略的知识, 开发一年多,工作中一直用传统springmvc的开发,基本都还是用的传统的xml配置开发, 看到书里有提到, ...
- shell脚本实现监控shell脚本的执行流程及变量的值
这篇文章主要介绍了shell脚本实现监控shell脚本的执行流程及变量的值本文使用shell完成对执行过程中条件语句中的变量的变化的监控和整个程序的执行流程的观察功能,需要的朋友可以参考下 很多时候, ...
- Linux时间子系统之七:定时器的应用--msleep(),hrtimer_nanosleep()【转】
转自:http://blog.csdn.net/droidphone/article/details/8104433 我们已经在前面几章介绍了低分辨率定时器和高精度定时器的实现原理,内核为了方便其它子 ...
- 【Linux技术】ubuntu常用命令【转】
转自:http://www.cnblogs.com/lcw/p/3159462.html 查看软件xxx安装内容:dpkg -L xxx查找软件库中的软件:apt-cache search 正则表达式 ...
- python使用twisted搭建的一个socket服务
服务端 # -*- coding: utf-8 -*- # @Time : 2018/9/19 21:41 # @Author : cxa # @File : tsTservTW.py # @Soft ...
- RESTful Web 服务:教程
RESTful Web 服务:教程 随着 REST 成为大多数 Web 和 Mobile 应用的默认选择,势必要对它的基本原理有所了解. 在它提出十多年后的今天,REST 已经成为最重要的 Web ...