BZOJ 4530 LCT/线段树合并
//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
int n,q,cnt,dfn[N],last[N],tree[N*],lson[N*],rson[N*];
int first[N],next[N],v[N],w[N],tot,root[N],fa[N],deep[N],f[N];
struct Node{int xx,yy;char op[];}node[N];
void dfs(int x){
dfn[x]=++cnt;
for(int i=first[x];~i;i=next[i])
if(v[i]!=fa[x])deep[v[i]]=deep[x]+,fa[v[i]]=x,dfs(v[i]);
last[x]=cnt;
}
void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void Add(int x,int y){add(x,y),add(y,x);}
void insert(int l,int r,int &pos,int num,int wei){
if(!pos)pos=++cnt;
if(l==r){tree[pos]=wei;return;}
int mid=(l+r)>>;
if(mid<num)insert(mid+,r,rson[pos],num,wei);
else insert(l,mid,lson[pos],num,wei);
tree[pos]=tree[lson[pos]]+tree[rson[pos]];
}
int query(int l,int r,int pos,int L,int R){
if(!pos)return ;
if(l>=L&&r<=R)return tree[pos];
int mid=(l+r)>>;
if(mid<L)return query(mid+,r,rson[pos],L,R);
else if(mid>=R)return query(l,mid,lson[pos],L,R);
else return query(l,mid,lson[pos],L,R)+query(mid+,r,rson[pos],L,R);
}
void merge(int pos1,int &pos2){
if(!pos2)pos2=++cnt;
tree[pos2]+=tree[pos1];
// printf("pos1=%d pos2=%d lson[pos1]=%d rson[pos1]=%d tree[pos]=%d\n",pos1,pos2,lson[pos1],rson[pos1],tree[pos2]);
if(lson[pos1])merge(lson[pos1],lson[pos2]);
if(rson[pos1])merge(rson[pos1],rson[pos2]);
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void dfs2(int x){
if(lson[x])dfs2(lson[x]);
if(rson[x])dfs2(rson[x]);
}
int main(){
memset(first,-,sizeof(first));
scanf("%d%d",&n,&q),getchar();
for(int i=;i<=q;i++){
scanf("%s%d%d",node[i].op,&node[i].xx,&node[i].yy);
if(node[i].op[]=='A')Add(node[i].xx,node[i].yy);
}
for(int i=;i<=n;i++)if(!fa[i])dfs(i);
cnt=;
for(int i=;i<=n;i++)insert(,n,root[i],dfn[i],),f[i]=i;
for(int i=;i<=q;i++){
if(node[i].op[]=='A'){
int fx=find(node[i].xx),fy=find(node[i].yy);
if(fx!=fy)merge(root[fx],root[fy]),f[fx]=fy;
}
else{
if(deep[node[i].xx]>deep[node[i].yy])swap(node[i].xx,node[i].yy);
int fy=find(node[i].yy);
long long temp=query(,n,root[fy],dfn[node[i].yy],last[node[i].yy]);
printf("%lld\n",(tree[root[fy]]-temp)*temp);
}
}
}
//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=;
int n,m,xx,yy,fa[N],ch[N][],rev[N],size[N],Size[N],q[N],top;
char op[];
bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
void push_up(int x){size[x]=size[ch[x][]]+size[ch[x][]]++Size[x];}
void push_down(int x){if(rev[x])rev[ch[x][]]^=,rev[ch[x][]]^=,swap(ch[x][],ch[x][]),rev[x]=;}
void rotate(int p){
int q=fa[p],y=fa[q],x=(ch[q][]==p);
ch[q][x]=ch[p][!x],fa[ch[q][x]]=q;
ch[p][!x]=q,fa[p]=y;
if(!isroot(q)){
if(ch[y][]==q)ch[y][]=p;
if(ch[y][]==q)ch[y][]=p;
}fa[q]=p,push_up(q);
}
void splay(int x){
q[++top]=x;
for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
while(top)push_down(q[top]),top--;
for(int y=fa[x];!isroot(x);rotate(x),y=fa[x])if(!isroot(y)){
if((ch[fa[y]][]==y)^(ch[y][]==x))rotate(x);
else rotate(y);
}push_up(x);
}
void access(int x){for(int t=;x;t=x,x=fa[x])splay(x),Size[x]+=size[ch[x][]]-size[t],ch[x][]=t,push_up(x);}
void makeroot(int x){access(x),splay(x),rev[x]^=;}
void link(int x,int y){makeroot(x),makeroot(y),fa[x]=y,Size[y]+=size[x],push_up(y);}
void split(int x,int y){makeroot(x),access(y),splay(x);}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)size[i]=;
while(m--){
scanf("%s%d%d",op,&xx,&yy);
if(op[]=='A')link(xx,yy);
else split(xx,yy),printf("%lld\n",1ll*(Size[yy]+)*(size[xx]-Size[yy]-));
}
}
BZOJ 4530 LCT/线段树合并的更多相关文章
- BZOJ #5457: 城市 [线段树合并]
线段树合并的板子题,每次从下到上合并就完事了 // by Isaunoya #include <bits/stdc++.h> using namespace std; #define re ...
- BZOJ 3779 LCT 线段树 DFS序 坑
hhhh抄了半天lty代码最后T了 对拍也没事.. 药丸 mine #pragma GCC optimize("O3") //By SiriusRen #include < ...
- [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】
题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...
- BZOJ.4399.魔法少女LJJ(线段树合并)
BZOJ 注意\(c\leq7\)→_→ 然后就是裸的权值线段树+线段树合并了. 对于取\(\max/\min\)操作可以直接区间修改清空超出范围的值,然后更新到对应位置上就行了(比如对\(v\)取\ ...
- BZOJ.5461.[PKUWC2018]Minimax(DP 线段树合并)
BZOJ LOJ 令\(f[i][j]\)表示以\(i\)为根的子树,权值\(j\)作为根节点的概率. 设\(i\)的两棵子树分别为\(x,y\),记\(p_a\)表示\(f[x][a]\),\(p_ ...
- BZOJ.3307.雨天的尾巴(dsu on tree/线段树合并)
BZOJ 洛谷 \(dsu\ on\ tree\).(线段树合并的做法也挺显然不写了) 如果没写过\(dsu\)可以看这里. 对修改操作做一下差分放到对应点上,就成了求每个点子树内出现次数最多的颜色, ...
- BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)
BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...
- BZOJ.5417.[NOI2018]你的名字(后缀自动机 线段树合并)
LOJ 洛谷 BZOJ 考虑\(l=1,r=|S|\)的情况: 对\(S\)串建SAM,\(T\)在上面匹配,可以得到每个位置\(i\)的后缀的最长匹配长度\(mx[i]\). 因为要去重,对\(T\ ...
- BZOJ 3277 串 & BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析、启发式合并、线段树合并、主席树)
标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) ...
随机推荐
- 将node-webkit打包后文件用nsis再打包成安装包
- Tensorflow Eager execution and interface
Lecture note 4: Eager execution and interface Eager execution Eager execution is (1) a NumPy-like li ...
- 推销员(codevs 5126)
题目描述 Description 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有N家住户,第i家住户到入口的距 ...
- Java面试常被问到的题目+解答
第一,anonymousinnerclass(匿名内部类)是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 不行,对于匿名内部类,看到的一句话说的 ...
- NYOJ5 Binary String Matching
Binary String Matching 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 Given two strings A and B, whose alp ...
- NetCore +EFCore+SqlServer根据数据库生成实体类到项目中
转载自:https://www.cnblogs.com/yangjinwang/p/9516988.html 1.点击“工具”->“NuGet包管理器”->“程序包管理器控制台” 分别安装 ...
- C#: 旋转图片到正确位置
当从iPhone等手机上传图片到服务器后,通常需要进行旋转处理,否则在进行图片压缩.缩放处理后会丢失正确的位置信息,导致显示的图片不处于正确的位置上. 处理的做法就是读取照片的Exif信息,并旋转到正 ...
- 错误代码: 1045 Access denied for user 'skyusers'@'%' (using password: YES)
1. 错误描写叙述 GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "."; 1 queries e ...
- j2se回想
执行Java程序. Java程序有两种方式一种是jar包.一种是class. 执行jar,Java -jar XXX.jar执行的时候,Java.exe调用GetMainClassName函数,该函数 ...
- Hibernate基于注解的双向one-to-many映射关系的实现
在项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现.可是公司的大部分都是基于注解的.因此自己參考之前的代码捣鼓了基于注解的一对多的映射关系实现. 背景: 一的一端:QingAo ...