[BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)
起床困难综合症那题,只要从高往低贪心,每次暴力跑一边看这一位输入0和1分别得到什么结果即可。
放到序列上且带修改,只要对每位维护一个线段树,每个节点分别记录0和1从左往右和从右往左走完这段区间后变成的数即可。
放到树上,只要树链剖分即可。但这里有一个很大的常数k,实际上我们只需要一个数就可以记录64个二进制位的信息,于是复杂度$O(n\log^2 n)$
小错误毁一生。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define ls (x<<1) 6 #define rs (ls|1) 7 #define lson ls,L,mid 8 #define rson rs,mid+1,R 9 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 10 #define For(i,x) for (int i=h[x],k; i; i=nxt[i]) 11 typedef unsigned long long ll; 12 using namespace std; 13 14 const int N=100010; 15 ll z,I=1; 16 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]; 17 int h[N],to[N<<1],nxt[N<<1]; 18 struct P{ int op; ll x; }p[N]; 19 struct D{ ll s0,s1; }v1[N<<2],v2[N<<2]; 20 struct S{ int l,r; }lp[N],rp[N]; 21 22 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } 23 24 void work(int x,P p){ 25 if (p.op==1) v1[x]=v2[x]=(D){0,p.x}; 26 if (p.op==2) v1[x]=v2[x]=(D){p.x,-1}; 27 if (p.op==3) v1[x]=v2[x]=(D){p.x,p.x^(-1)}; 28 } 29 30 D operator +(D a,D b){ return (D){((~a.s0)&b.s0)|(a.s0&b.s1),((~a.s1)&b.s0)|(a.s1&b.s1)}; } 31 void upd(int x){ v1[x]=v1[ls]+v1[rs]; v2[x]=v2[rs]+v2[ls]; } 32 33 void dfs(int x){ 34 sz[x]=1; dep[x]=dep[fa[x]]+1; 35 For(i,x) if ((k=to[i])!=fa[x]){ 36 fa[k]=x; dfs(k); sz[x]+=sz[k]; 37 if (sz[k]>sz[son[x]]) son[x]=k; 38 } 39 } 40 41 void dfs2(int x,int tp){ 42 top[x]=tp; dfn[x]=++tim; pos[tim]=x; 43 if (son[x]) dfs2(son[x],tp); 44 For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k); 45 } 46 47 void build(int x,int L,int R){ 48 if (L==R){ work(x,p[pos[L]]); return; } 49 int mid=(L+R)>>1; 50 build(lson); build(rson); upd(x); 51 } 52 53 void mdf(int x,int L,int R,int pos,P p){ 54 if (L==R){ work(x,p); return; } 55 int mid=(L+R)>>1; 56 if (pos<=mid) mdf(lson,pos,p); else mdf(rson,pos,p); 57 upd(x); 58 } 59 60 D que(int x,int L,int R,int l,int r,int k){ 61 if (L==l && r==R) return (k==1) ? v1[x] : v2[x]; 62 int mid=(L+R)>>1; 63 if (r<=mid) return que(lson,l,r,k); 64 else if (l>mid) return que(rson,l,r,k); 65 else{ 66 D a=que(lson,l,mid,k),b=que(rson,mid+1,r,k); 67 return (k==1) ? a+b : b+a; 68 } 69 } 70 71 void solve(int x,int y,ll z){ 72 int ld=0,rd=0,rev=0; 73 S *L=lp,*R=rp; 74 for (; top[x]!=top[y]; x=fa[top[x]]){ 75 if (dep[top[x]]<dep[top[y]]) rev^=1,swap(x,y),swap(ld,rd),swap(L,R); 76 L[++ld]=(S){dfn[top[x]],dfn[x]}; 77 } 78 if (dep[x]<dep[y]) rev^=1,swap(x,y),swap(ld,rd),swap(L,R); 79 L[++ld]=(S){dfn[y],dfn[x]}; 80 if (rev) swap(ld,rd),swap(L,R); 81 D res=(D){0,-1}; 82 rep(i,1,ld) res=res+que(1,1,n,L[i].l,L[i].r,2); 83 for (int i=rd; i; i--) res=res+que(1,1,n,R[i].l,R[i].r,1); 84 ll s=0,c=0; 85 for (int i=k-1; ~i; i--) 86 if (res.s0&(I<<i)) s+=I<<i; 87 else if ((res.s1&(I<<i)) && c+(I<<i)<=z) c+=I<<i,s+=I<<i; 88 printf("%llu\n",s); 89 } 90 91 int main(){ 92 freopen("bzoj4811.in","r",stdin); 93 freopen("bzoj4811.out","w",stdout); 94 scanf("%d%d%d",&n,&m,&k); 95 rep(i,1,n) scanf("%d%llu",&p[i].op,&p[i].x); 96 rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u); 97 dfs(1); dfs2(1,1); build(1,1,n); 98 rep(i,1,m){ 99 scanf("%d%d%d%llu",&op,&x,&y,&z); 100 if (op==1) solve(x,y,z); else mdf(1,1,n,dfn[x],(P){y,z}); 101 } 102 return 0; 103 }
转载于:https://www.cnblogs.com/HocRiser/p/10129342.html
[BZOJ4811][YNOI2017]由乃的OJ(树链剖分+线段树)相关推荐
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MB Submit: 1153 Solved: 421 [Submit][Sta ...
- BZOJ3862Little Devil I——树链剖分+线段树
题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...
- CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)
题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...
- CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)
题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...
- P2486 [SDOI2011]染色(树链剖分+线段树)
题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...
- BZOJ4127Abs——树链剖分+线段树
题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树
题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...
- YbtOJ-染色计划【树链剖分,线段树,tarjan】
正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...
最新文章
- 拆解交易系统--如何做好稳定性
- “大型票务系统”和“实物电商系统”的数据库选型
- AttributeError: ‘Model‘ object has no attribute ‘_get_distribution_strategy
- OpenHarmony和HarmonyOS有什么区别?这篇文章讲清楚了
- CentOS7部署(Mysql) MariaDB Galera Cluster 10.1记录
- android view 存值,使用ViewModel保存数据
- IPTV Checker(直播源自动检测工具)
- android 阅读器字体,为 Android 换上任意喜欢的字体,你可以试试这个 Magisk 模块...
- 计算机网络 全章节思维导图
- [4G5G专题-50]:物理层-数字波束赋型Beamforming及其数学原理
- 用GNS3制作路由交换网络拓扑图
- vue实现带图片的标题栏
- FLINK 极客时间
- 在浏览器中嵌入播放器
- 爬虫(一):用python爬取亚马逊所有家具种类前100名的商品信息(上)
- A Sample Crash Log
- 快速排序算法(图解+代码)
- 2022-2028年中国渗滤液行业市场运行态势及发展战略研究报告
- echarts lengend格式化和换行
- Excel函数--SUM计算累计销量