(Luogu) P3950 部落冲突 (LCT || 树链剖分)

2024-03-20 16:58

本文主要是介绍(Luogu) P3950 部落冲突 (LCT || 树链剖分),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传送门

解:LCT解决这个就非常直接了,直接断边连边,检查一下连通性就行了。

#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
#define ls ch[x][0]
#define rs ch[x][1]
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=3e5+5;
template <typename _Tp> il void read(_Tp&x) {char ch;bool flag=0;x=0;while(ch=getchar(),!isdigit(ch)) if(ch=='-')flag=1;while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();if(flag) x=-x;
}
//il int Add(int &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(int &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
int f[N],ch[N][2],v[N],s[N],st[N],sz[N];
bool r[N];
il bool isroot(int x){return ch[f[x]][0]==x || ch[f[x]][1]==x; 
} 
il void pushup(int x){sz[x]=sz[ls]+sz[rs]+1; 
}
il void reverse(int x){swap(ls,rs),r[x]^=1;
}
il void pushdown(int x){if(r[x]){if(ls) reverse(ls);if(rs) reverse(rs);r[x]=0;}
}
il void rotate(int x){int y=f[x],z=f[y],k=(ch[y][1]==x),w=ch[x][!k];if(isroot(y))	ch[z][ch[z][1]==y]=x;ch[x][!k]=y,ch[y][k]=w;if(w) f[w]=y;f[y]=x,f[x]=z;pushup(y);
}
il void splay(int x){int y=x,z=0;st[++z]=y;while(isroot(y)) st[++z]=y=f[y];while(z) pushdown(st[z--]);while(isroot(x)){y=f[x],z=f[y];if(isroot(y)) rotate((ch[y][0]==x)^(ch[z][0]==y)?x:y);rotate(x);}pushup(x);
}il void access(int x){for(int y=0;x;x=f[y=x]){splay(x),rs=y,pushup(x);}
}
il void makeroot(int x){access(x),splay(x);reverse(x);
}
il int findroot(int x){//查找在原树的根 access(x),splay(x);while(ls) pushdown(x),x=ls;splay(x);return x;
}
il void split(int x,int y){makeroot(x);access(y),splay(y);
}
//保证合法的情况下 
il void link(int x,int y){makeroot(x),f[x]=y;
}
il void cut(int x,int y){split(x,y);f[x]=ch[y][0]=0;
}int n,m;
char op[2];
struct node{int u,v;
}q[N];
int main() {read(n),read(m);int x,y,cnt=0;for(int i=1;i<=n-1;++i){read(x),read(y);link(x,y);}while(m--){scanf("%s",op);if(op[0]=='Q'){read(x),read(y);if(findroot(x)==findroot(y)) printf("Yes\n");else printf("No\n");}else if(op[0]=='C'){read(x),read(y);q[++cnt]={x,y};cut(x,y);}else{read(x);link(q[x].u,q[x].v);}}return 0;
}

解:当边上有战争时,那就将这条边+1,查询x能否到y,就是查询x到y的路径权值和是否为0,树剖本来维护点,我们将每条边分给边上深度较大的一个点上,无论是修改还是查询操作,先全部算上,然后只要对x,y的最近公共祖先取消他的操作就可以了。


#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
#define mid ((l+r)>>1)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=3e5+5; 
template <typename _Tp> il void read(_Tp&x) {char ch;bool flag=0;x=0;while(ch=getchar(),!isdigit(ch)) if(ch=='-')flag=1;while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();if(flag) x=-x;
}
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
vector<int> G[N]; 
int n,m,dep[N],sz[N],son[N],fa[N],id[N],bel[N],cnt;
il void dfs1(int x,int ff){fa[x]=ff,dep[x]=dep[ff]+1,sz[x]=1;int mx=-1;for(auto to:G[x]){if(to==ff) continue;dfs1(to,x);sz[x]+=sz[to];if(sz[to]>mx) son[x]=to,mx=sz[to];}
} 
il void dfs2(int x,int topx){id[x]=++cnt,bel[x]=topx;if(!son[x]) return ;dfs2(son[x],topx);for(auto to:G[x]){if(to==fa[x] || to==son[x]) continue;dfs2(to,to);} 
}
int lz[N<<2],s[N<<2],tsz[N<<2];
il void pushdown(int rt){if(lz[rt]){lz[rt<<1]+=lz[rt],lz[rt<<1|1]+=lz[rt];s[rt<<1]+=tsz[rt<<1]*lz[rt];s[rt<<1|1]+=tsz[rt<<1|1]*lz[rt];lz[rt]=0;}
} 
il void build(int l,int r,int rt){if(l==r){tsz[rt]=1;return;}build(l,mid,rt<<1);build(mid+1,r,rt<<1|1);tsz[rt]=tsz[rt<<1]+tsz[rt<<1|1];
}
il void update(int l,int r,int rt,int L,int R,int C){if(L<=l && r<=R){s[rt]+=C*tsz[rt],lz[rt]+=C;return;}pushdown(rt);if(L<=mid) update(l,mid,rt<<1,L,R,C);if(R>mid) update(mid+1,r,rt<<1|1,L,R,C);s[rt]=s[rt<<1]+s[rt<<1|1];
}
il int query(int l,int r,int rt,int L,int R){if(L<=l && r<=R){return s[rt];}int ans=0;pushdown(rt);if(L<=mid) ans+=query(l,mid,rt<<1,L,R);if(R>mid) ans+=query(mid+1,r,rt<<1|1,L,R);return ans;
} 
il void r_update(int x,int y,int w){while(bel[x]!=bel[y]){if(dep[bel[x]]<dep[bel[y]]) swap(x,y);update(1,n,1,id[bel[x]],id[x],w);x=fa[bel[x]];}if(dep[x]>dep[y]) swap(x,y);update(1,n,1,id[x],id[y],w);update(1,n,1,id[x],id[x],-w);
}
il int r_ask(int x,int y){int res=0;while(bel[x]!=bel[y]){if(dep[bel[x]]<dep[bel[y]]) swap(x,y);res+=query(1,n,1,id[bel[x]],id[x]);x=fa[bel[x]];}if(dep[x]>dep[y]) swap(x,y);res+=query(1,n,1,id[x],id[y]);res-=query(1,n,1,id[x],id[x]);return res;
}
char op[2];
struct node{int u,v;
}q[N];
int main(){read(n),read(m);int x,y,tot=0;for(int i=1;i<=n-1;++i){read(x),read(y);G[x].pb(y),G[y].pb(x);}dfs1(1,0);dfs2(1,1);build(1,n,1);while(m--){scanf("%s",op);if(op[0]=='Q'){read(x),read(y);if(r_ask(x,y)==0) printf("Yes\n");else printf("No\n");}else if(op[0]=='C'){read(x),read(y);q[++tot]={x,y};r_update(x,y,1);}else{read(x);r_update(q[x].u,q[x].v,-1);}}return 0;
}

 

这篇关于(Luogu) P3950 部落冲突 (LCT || 树链剖分)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/830144

相关文章

vue+elementui分页输入框回车与页面中@keyup.enter事件冲突解决

解决这个问题的思路只要判断事件源是哪个就好。el分页的回车触发事件是在按下时,抬起并不会再触发。而keyup.enter事件是在抬起时触发。 so,找不到分页的回车事件那就拿keyup.enter事件搞事情。只要判断这个抬起事件的$event中的锚点样式判断不等于分页特有的样式就可以了 @keyup.enter="allKeyup($event)" //页面上的//js中allKeyup(e

SPOJ - QTREE (树链剖分)

基础的树链剖分题目,不过是边权,可以向下映射成点权或者按边剖分。 VIEW CODE #include <iostream>#include<stdio.h>#include<cmath>#include<string.h>#include<algorithm>#include<string>using namespace std;const int mmax=100

无法解决 equal to 运算中 Chinese_PRC_90_CI_AS 和 Chinese_PRC_BIN 之间的排序规则冲突

这是因为数据库 oa 和 hh 的编码格式不一样导致的 select  groupname as oper_id,name as oper_name from security_users where name collate Chinese_PRC_CI_AS not in (select oper_name from PDA_UsersAndPWD )

【Android面试八股文】你能说一说在平常开发过程中你是如何解决事件冲突问题的吗?

文章目录 一、内部拦截法(Inner Intercept)1.1 工作原理:1.2 实现步骤:1.3 适用场景:1.4 内部拦截法示例1.4.1. 自定义 `RecyclerView` 以处理内部拦截1.4.2. 在布局中使用 `InterceptableRecyclerView` 1.5 为什么`requestDisallowInterceptTouchEvent(boolean disa

maven常用命令以及jar依赖冲突

1 命令 1.1 常用命令 mvn validate 验证项目是否正确 mvn package maven打包 mvn generate-sources 生成源代码 mvn compile 编译 mvn test-compile 编译测试代码 mvn test 运行测试 mvn verify 运行检查 mvn clean 清理项目 mvn install 安装项目到本地仓库 mvn deplo

多Qt版本冲突导致编译异常的解决方法

在VS2015+Qt5.8.0(或VS2013+Qt5.6.2等等)中新建Qt Application项目,没有任何改动,编译依然报错如下: error MSB6006: “cmd.exe”已退出,代码为 9009 解决方法如下: 1.检查Qt安装目录是否添加到环境变量: VS2013+Qt5.6.2配置 VS2015+Qt5.8.0配置

一个页面中需要多个window.onload = function(){}冲突问题解决

今天在写js作业的时候,没注意用到了几个 window.onload,发现打开测试的时候有冲突,导致没有效果出现。上网查阅了资料,发现解决办法。 如果在一个页面中有两个JavaScript 分别都用到了window.onload 一个是:window.οnlοad=function(a){...},另一个是:window.οnlοad=function(b){...} 就造成了一个JavaS

[HDU 5029] Relief grain (树链剖分+线段树)

HDU - 5029 其实这道题最大的难点不是树链剖分,而是怎么维护某个点被那些颜色染过,染过多少次 如果在线段树维护的话,很难做到,估计得树套树,而且空间会炸 好在这题是离线的,可以使用差分的思想来维护 对一段区间[l,r]染色 c,相当于在这段区间左端点 l打上 c标志,右端点 r+1打上 -c标志 然后扫一遍整个区间 (依照 dfs序扫一遍整棵树),期间不断维护一颗线段树 线段树

idea解决git代码冲突,提交代码冲突如何有效解决

当在提交代码的时候遇到问题冲突,是已经进行git commit , 但是在 git push 的时候,出现提交代码问题冲突  处理方式: 在IDEA 左下角,找到git  比如在git commint 之前忘记了 git pull ,那么很容易在git push 的时候出现问题,尤其是前后端在一起的那种。 找到commit 之前的分支,右键选择:Reset Curret Bran

docker容器网络与宿主机网络冲突的原因与解决方案

一、故障现象 在用docker-compos.yaml文件或者手动创建docker网络时,可能会出现新建的容器网络与宿主机网络冲突,导致SSH远程连接中断,并无法再用Xshell等远程连接工具连接宿主机。现象如下: [root@controller ~]# docker network create ptuxgk5Socket error Event: 32 Error: 10053.Con