【Luogu】P3950部落冲突(树链剖分)
状态奇差无比,sbt都能错一遍。
不动笔光想没有想到怎么做,画图之后发现一个很明显的性质……
那就是两个开战的部落,其中一个是另一个的父亲。
所以在儿子那里加个权值。查询的时候树链剖分查询链上点权和,减去lca的点权(因为lca那如果有点权,代表的是lca和lca的父亲之间的那条边)。
- #include<cstdio>
- #include<algorithm>
- #include<cctype>
- #include<cstring>
- #include<cstdlib>
- #define left (rt<<1)
- #define right (rt<<1|1)
- #define mid ((l+r)>>1)
- #define lson l,mid,left
- #define rson mid+1,r,right
- #define maxn 300050
- using namespace std;
- inline long long read(){
- long long num=,f=;
- char ch=getchar();
- while(!isdigit(ch)){
- if(ch=='-') f=-;
- ch=getchar();
- }
- while(isdigit(ch)){
- num=num*+ch-'';
- ch=getchar();
- }
- return num*f;
- }
- struct Edge{
- int next,to;
- }edge[maxn*];
- int head[maxn],num;
- inline void add(int from,int to){
- edge[++num]=(Edge){head[from],to};
- head[from]=num;
- }
- int tree[maxn*];
- int dfn[maxn];
- int deep[maxn];
- int father[maxn];
- int size[maxn];
- int top[maxn];
- int son[maxn];
- int ID,n,m;
- void unifnd(int x,int fa){
- deep[x]=deep[fa]+; size[x]=;
- for(int i=head[x];i;i=edge[i].next){
- int to=edge[i].to;
- if(to==fa) continue;
- father[to]=x;
- unifnd(to,x);
- size[x]+=size[to];
- if(son[x]==||size[son[x]]<size[to]) son[x]=to;
- }
- }
- void unionn(int x,int Top){
- dfn[x]=++ID; top[x]=Top;
- if(son[x]==) return;
- unionn(son[x],Top);
- for(int i=head[x];i;i=edge[i].next){
- int to=edge[i].to;
- if(to==father[x]||to==son[x]) continue;
- unionn(to,to);
- }
- }
- inline void pushup(int rt){
- tree[rt]=tree[left]+tree[right];
- }
- void update(int o,int num,int l,int r,int rt){
- if(l==r){
- tree[rt]+=num;
- return;
- }
- if(o<=mid) update(o,num,lson);
- else update(o,num,rson);
- pushup(rt);
- return;
- }
- int query(int from,int to,int l,int r,int rt){
- if(from<=l&&to>=r) return tree[rt];
- int ans=;
- if(from<=mid) ans+=query(from,to,lson);
- if(to>mid) ans+=query(from,to,rson);
- return ans;
- }
- struct War{
- int from,to;
- }q[maxn];int cnt;
- inline void adds(int from,int to){
- if(deep[from]<deep[to]) swap(from,to);
- q[++cnt]=(War){from,to};
- update(dfn[from],,,n,);
- return;
- }
- inline void del(int rnk){
- int from=q[rnk].from;
- update(dfn[from],-,,n,);
- }
- inline int LCA(int from,int to){
- while(top[from]!=top[to]){
- if(deep[top[from]]<deep[top[to]]) swap(from,to);
- from=father[top[from]];
- }
- if(deep[from]>deep[to]) swap(from,to);
- return from;
- }
- inline int ask(int from,int to){
- int lca=LCA(from,to),ans=-query(dfn[lca],dfn[lca],,n,);
- while(top[from]!=top[to]){
- if(deep[top[from]]<deep[top[to]]) swap(from,to);
- ans+=query(dfn[top[from]],dfn[from],,n,);
- if(ans>) return ;
- from=father[top[from]];
- }
- if(deep[from]>deep[to]) swap(from,to);
- ans+=query(dfn[from],dfn[to],,n,);
- if(ans>) return ;
- return ;
- }
- int main(){
- n=read(),m=read();
- for(int i=;i<n;++i){
- int x=read(),y=read();
- add(x,y);
- add(y,x);
- }
- unifnd(,);
- unionn(,);
- for(int i=;i<=m;++i){
- char c[];
- scanf("%s",c);
- if(c[]=='Q'){
- int x=read(),y=read();
- if(ask(x,y)) printf("Yes\n");
- else printf("No\n");
- }
- else if(c[]=='C'){
- int x=read(),y=read();
- adds(x,y);
- }
- else{
- int x=read();
- del(x);
- }
- }
- return ;
- }
【Luogu】P3950部落冲突(树链剖分)的更多相关文章
- luogu题解 P3950部落冲突--树链剖分
题目链接 https://www.luogu.org/problemnew/show/P3950 分析 大佬都用LCT,我太弱只会树链剖分 一个很裸的维护边权树链剖分题.按照套路,对于一条边\(< ...
- 洛谷 P3950 部落冲突 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例1 输出样例1 输入样例2 输出样例2 输入样例3 输出样例3 说明 思路 AC代码 总结 题面 题目链接 P3 ...
- Luogu P2486 [SDOI2011]染色(树链剖分+线段树合并)
Luogu P2486 [SDOI2011]染色 题面 题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例: 6 5 2 2 1 2 1 1 1 ...
- Luogu P2486 染色(树链剖分+线段树)
题解 不妨采取重链剖分的方式把路径剖成区间,然后用线段树维护,考虑如何合并一个区间 struct Node { int lf, rg, tot; }seg[N << 2]; int col ...
- 【luogu P3950 部落冲突】 题解
题目连接:https://www.luogu.org/problemnew/show/P3950 1.像我这种学数据结构学傻了的 2.边权化点权 所有点权初始化0 3.对于战争 将深度较深的-1,对于 ...
- luogu P3950 部落冲突
嘟嘟嘟 树剖板子题. #include<cstdio> #include<iostream> #include<algorithm> #include<cma ...
- 【题解】Luogu P3950 部落冲突
原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 我们用Link-Cut-Tree维护连通性(十分无脑) 一开始先把树中每条边的两端连接 U操作:把u,v两个点连起来 ...
- lupgu P3950 部落冲突
题目链接 luogu P3950 部落冲突 题解 树剖线段树可以 lct还行 代码 #include<cstdio> #include<algorithm> inline in ...
- 洛谷P2590 [ZJOI2008]树的统计 题解 树链剖分+线段树
题目链接:https://www.luogu.org/problem/P2590 树链剖分模板题. 剖分过程要用到如下7个值: fa[u]:u的父节点编号: dep[u]:u的深度: size[u]: ...
随机推荐
- 使用JDK自带的VisualVM进行Java程序的性能分析
VisualVM是什么? VisualVM是JDK自带的一个用于Java程序性能分析的工具,JDK安装完毕后就有啦,在JDK安装目录的bin文件夹下能找到名称为jvisualvm.exe. 要使用Vi ...
- 读书笔记2013-2 Linux内核设计与实现A
读书笔记2013-2 Linux内核设计与实现A <Linux内核设计与实现> 简介 这本书不是想Linux源码剖析那样一行行分析Linux源代码的书,而是从Linux历史,Linux哲学 ...
- Uva 127 poj 1214 `Accordian'' Patience 纸牌游戏 模拟
Input Input data to the program specifies the order in which cards are dealt from the pack. The inpu ...
- 解决在matplotlib使用中文的问题
原生的matplotlib并不支持直接使用中文,而需要修改一下相应的文件,上网搜了下,找到一个最简洁的办法. NO.1 找到matplotlibrc文件 C:\Python26\Lib\site-pa ...
- 51nod——1548 欧姆诺姆和糖果
一开始以为是贪心,然后发现没法贪.暴力枚举肯定T,于是用约束关系优化: 假设wr >= wb, 第一种情况:wr >= sqrt (c), 则此时最多吃c / wr个r,且c / wr & ...
- Codeforces 517 #A
http://codeforces.com/contest/1072/problem/A 题目挺简单,就是让你求几个环,占得方格的个数,然而题目为什么给出了公式呢? 然而给出的公式辣么丑,还是不用的好 ...
- C++ 学习笔记 开篇
从大一开始学习C语言,大学期间做了许多嵌入式的开发项目,毕业后从事嵌入式开发工作主要的开发语言也是C语言.虽然期间断断续续的学习过C++,做过QT.C#上位机但也只是在其他语言的外壳下使用C在开发,始 ...
- JS正则表达式学习总结
JS正则:java RegExp对象,它是对字符串执行模式匹配的强大工具.运用最多的就是在输入处验证输入的字符串是否合法,指定用户输入字符串的格式. 定义方法: 1:直接量语法:var re=/pat ...
- 二分查找、upper_bound、lower_bound
整理及总结二分查找的判断和边界细节 修改版 package com.leej.binarysearch; import java.util.Arrays; /** * @author jerry * ...
- tempfs详解
致因 在平常工作中,我们经常需要查看Linux服务器磁盘挂载使用情况,可以使用df命令,不知大家注意到没有,我们使用此命令除了会查看到系统盘以及数据盘挂载情况,还会看到一个tmpfs也在挂载. [ro ...