重庆网站建设接重庆零臻科技,wordpress发帖软件,wordpress分类排序号,创意设计文案正题
题目链接:https://gmoj.net/senior/#main/show/4739 题目大意 nnn个点mmm条边的一张图#xff0c;qqq次询问一个区间的边可以形成多少连通块。 解题思路
询问按照右端点排序#xff0c;然后边权就是编号#xff0c;这样询问最大生成树后判断有多少个边权大于lll即可。…正题
题目链接:https://gmoj.net/senior/#main/show/4739 题目大意
nnn个点mmm条边的一张图qqq次询问一个区间的边可以形成多少连通块。 解题思路
询问按照右端点排序然后边权就是编号这样询问最大生成树后判断有多少个边权大于lll即可。用LCTLCTLCT维护这个最大生成树然后用树状数组记录每条边的权值。
时间复杂度O(nlogn)O(n\log n)O(nlogn)
当然也可以莫队做维护到每个块时的情况然后右指针右移左指针右移是暴力还原到每个块的末尾即可。
时间复杂度O(nn)O(n\sqrt n)O(nn)
当然这里是用LCTLCTLCT做的。 codecodecode
#includecstdio
#includecstring
#includealgorithm
#includestack
#define lowbit(x) (x-x)
using namespace std;
const int N4e510;
struct node{int x,y,id;
}a[N],p[N];
int n,m,q,val[N],sum[N],ans[N],fa[N];
struct Link_Cut_Tree{int t[N][2],fa[N];bool r[N];stackints;bool Nroot(int x){return fa[x](t[fa[x]][0]x||t[fa[x]][1]x);}bool Direct(int x){return t[fa[x]][1]x;}void PushUp(int x){sum[x]min(val[x],min(sum[t[x][0]],sum[t[x][1]]));return;}void Rev(int x){swap(t[x][0],t[x][1]);r[x]^1;return;}void PushDown(int x){if(!r[x])return;Rev(t[x][0]);Rev(t[x][1]);r[x]^1;return;}void Rotate(int x){int yfa[x],zfa[fa[x]];int xsDirect(x),ysDirect(y);int wt[x][!xs];t[y][xs]0;t[y][xs]w;t[x][!xs]y;if(Nroot(y))t[z][ys]x;if(w)fa[w]y;fa[y]x;fa[x]z;PushUp(y);PushUp(x);return;}void Splay(int x){s.push(x);while(Nroot(s.top())) s.push(fa[s.top()]);while(!s.empty()) PushDown(s.top()),s.pop();while(Nroot(x)){int yfa[x];if(!Nroot(y))Rotate(x);else if(Direct(x)Direct(y))Rotate(y),Rotate(x);else Rotate(x),Rotate(x); }return;}void Access(int x){for(int y0;x;xfa[yx])Splay(x),t[x][1]y,PushUp(x);return;}void MakeRoot(int x){Access(x);Splay(x);Rev(x);return;}int Split(int x,int y){MakeRoot(x);Access(y);Splay(y);return sum[y];}void Link(int x,int y){MakeRoot(x);fa[x]y;Access(x);return;}void Cut(int x,int y){MakeRoot(y);Access(x);Splay(x);fa[t[x][0]]0;t[x][0]0;PushUp(x);return;}
}LCT;
struct Tree_Array{int t[N];void Change(int x,int val){while(xm){t[x]val;xlowbit(x);}return;}int Ask(int x){int ans0;while(x){anst[x];x-lowbit(x);}return ans;}
}T;
int find(int x)
{return (fa[x]x)?x:(fa[x]find(fa[x]));}
bool cmp(node x,node y)
{return x.yy.y;}
int main()
{scanf(%d%d%d,n,m,q);memset(val,0x3f,sizeof(val));memset(sum,0x3f,sizeof(sum));for(int i1;in;i)fa[i]i;for(int i1;im;i){scanf(%d%d,a[i].x,a[i].y);val[in]sum[in]i;}for(int i1;iq;i)scanf(%d%d,p[i].x,p[i].y),p[i].idi;sort(p1,p1q,cmp);int z0;for(int i1;iq;i){while(zmzp[i].y){z;int xa[z].x,ya[z].y;if(xy)continue;int Xfind(x),Yfind(y);if(XY){int wLCT.Split(x,y);LCT.Cut(wn,a[w].x);LCT.Cut(wn,a[w].y);T.Change(w,-1);}else fa[X]Y;LCT.Link(x,zn);LCT.Link(y,zn);T.Change(z,1);}ans[p[i].id]n-(T.Ask(p[i].y)-T.Ask(p[i].x-1));}for(int i1;iq;i)printf(%d\n,ans[i]);
}