Ztxz16学图论
来源:互联网 发布:unity3d 汽车模型 编辑:程序博客网 时间:2024/05/29 18:55
题目大意
给定一张图,每次询问编号在[l,r]的边连上后会形成多少联通块。
离线做法
我们考虑莫队。
考虑左端点所在的每一块,左端点到块末最多根号的距离,右端点是单调的。并查集容易添加,因此只保留块末到右端点的联通情况,每次暴力加上块末到左端点部分。
在线做法
把加入1~i条边,每条边权值设置为编号,所形成的最大生成树叫第i个版本。
[l,r]的答案=第r个版本中联通块数量+第r个版本中[1,l-1]存在树中的数量
依次加上每条边,用LCT维护得到每个版本,然后得到其联通块数量。可持久化线段树来保存每个版本中边的出现情况。
#include<cstdio>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=200000+10,maxtot=8000000+10;int father[maxn*2],key[maxn*2],num[maxn*2],tree[maxn*2][2],pp[maxn*2];bool bz[maxn*2];int ans[maxn],root[maxn],left[maxtot],right[maxtot],sum[maxtot],fa[maxn],edge[maxn][2],sta[maxn*2];int i,j,k,l,r,t,n,m,q,tot,top,cnt,now;int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*f;}int getfa(int x){ return fa[x]?fa[x]=getfa(fa[x]):x;}int pd(int x){ return tree[father[x]][1]==x;}void update(int x){ num[x]=x; if (tree[x][0]) if (key[num[tree[x][0]]]<key[num[x]]) num[x]=num[tree[x][0]]; if (tree[x][1]) if (key[num[tree[x][1]]]<key[num[x]]) num[x]=num[tree[x][1]];}void rotate(int x){ int y=father[x],z=pd(x); father[x]=father[y]; if (father[y]) tree[father[y]][pd(y)]=x; tree[y][z]=tree[x][1-z]; if (tree[x][1-z]) father[tree[x][1-z]]=y; tree[x][1-z]=y; father[y]=x; update(y); update(x); if (pp[y]){ pp[x]=pp[y]; pp[y]=0; }}void clear(int x){ if (bz[x]){ bz[tree[x][0]]^=1; bz[tree[x][1]]^=1; swap(tree[x][0],tree[x][1]); bz[x]=0; }}void remove(int x,int y){ cnt=0; while (x!=y){ sta[++cnt]=x; x=father[x]; } while (cnt){ clear(sta[cnt]); cnt--; }}void splay(int x,int y){ remove(x,y); while (father[x]!=y){ if (father[father[x]]!=y) if (pd(x)==pd(father[x])) rotate(father[x]);else rotate(x); rotate(x); }}void access(int x){ int y; splay(x,0); if (tree[x][1]){ pp[tree[x][1]]=x; father[tree[x][1]]=0; tree[x][1]=0; update(x); } while (x){ splay(x,0); y=pp[x]; if (!y) break; splay(y,0); if (tree[y][1]){ pp[tree[y][1]]=y; father[tree[y][1]]=0; } tree[y][1]=x; pp[x]=0; father[x]=y; update(y); x=y; }}void makeroot(int x){ access(x); splay(x,0); bz[x]^=1;}int newnode(int x){ sum[++top]=sum[x]; left[top]=left[x]; right[top]=right[x]; return top;}void change(int &p,int l,int r,int a,int b){ p=newnode(p); sum[p]+=b; if (l==r) return; int mid=(l+r)/2; if (a<=mid) change(left[p],l,mid,a,b);else change(right[p],mid+1,r,a,b);}int query(int p,int l,int r,int a,int b){ if (a>b) return 0; if (l==a&&r==b) return sum[p]; int mid=(l+r)/2; if (b<=mid) return query(left[p],l,mid,a,b); else if (a>mid) return query(right[p],mid+1,r,a,b); else return query(left[p],l,mid,a,mid)+query(right[p],mid+1,r,mid+1,b);}void write(int x){ if (!x){ putchar('0'); putchar('\n'); return; } cnt=0; while (x){ sta[++cnt]=x%10; x/=10; } while (cnt){ putchar(sta[cnt]+'0'); cnt--; } putchar('\n');}int main(){ n=read();m=read();q=read(); tot=now=n; fo(i,1,n) key[i]=m+1,num[i]=i; fo(i,1,m){ j=read();k=read(); edge[i][0]=j;edge[i][1]=k; root[i]=root[i-1]; tot++; key[tot]=i; num[tot]=tot; if (j==k){ ans[i]=ans[i-1]; continue; } if (getfa(j)!=getfa(k)){ fa[getfa(k)]=getfa(j); now--; makeroot(k); splay(k,0); pp[k]=tot; pp[tot]=j; change(root[i],1,m,i,1); } else{ makeroot(j); access(k); splay(k,0); l=num[k]; change(root[i],1,m,l-n,-1); makeroot(l); access(l); splay(edge[l-n][0],0); pp[edge[l-n][0]]=0; splay(edge[l-n][1],0); pp[edge[l-n][1]]=0; makeroot(k); splay(k,0); pp[k]=tot; pp[tot]=j; change(root[i],1,m,i,1); } ans[i]=now; } while (q--){ l=read();r=read(); now=ans[r]; now+=query(root[r],1,m,1,l-1); write(now); }}
0 0
- Ztxz16学图论
- Ztxz16学图论
- JZOJ4739. Ztxz16学图论
- [CodeChef]GERALD07/[JZOJ4739]Ztxz16学图论
- 【搬自CC_GERALD07】【JZ雅礼联考】Ztxz16学图论 题解
- 【雅礼联考GDOI2017模拟9.2】Ztxz16学图论
- 【雅礼联考GDOI2017模拟9.2】Ztxz16学图论
- JZOJ 4739 【雅礼联考GDOI2017模拟9.2】Ztxz16学图论
- 【雅礼联考GDOI2017模拟9.2】Ztxz16学图论
- JZOJ4739 【雅礼联考GDOI2017模拟9.2】Ztxz16学图论 莫队加并查集
- JZOJ4739. 【雅礼联考GDOI2017模拟9.2】Ztxz16学图论(2017.8B组)
- 【CDOJ1152】小panpan学图论
- CDOJ 1152 小panpan学图论
- SCU 4525 meixiuxiu学图论(kruskal)
- [SCU 4525] meixiuxiu学图论 (二分答案 | 最小生成树)
- Git
- 【蒻爆了的NOIP系列--普及组复赛】(3)NOIP2012普及组复赛题解
- TCP标志位#转载#
- TCP标志位
- 为什么上论坛,会显示我的浏览器和系统版本呢?
- Ztxz16学图论
- Android调试笔记——FATAL EXCEPTION: main...have you declared this activity in your AndroidManifest.xml?
- [分块 暴力 树] BZOJ 4381 [POI2015]Odwiedziny
- [LeetCode] 129. Sum Root to Leaf Numbers
- [鬼畜 树链剖分 线段树] BZOJ 2814 tree
- c# 笔记整理(2016年9月4日)
- 利用Android Studio创建AIDL并使用AIDL
- 利用Matlab绘制梯度图、散度图、旋度图
- 多线程基础