[LCT 树状数组] HDU 5333 Undirected Graph
2017-02-07 16:37
363 查看
这个题跟 [LCT 主席树] BZOJ 3514 Codechef MARCH14 GERALD07加强版有异曲同工之妙
考虑询问按右端点排序
对于一条边 边的权值定义为较小的一端的编号
那么显然权值大的边更有利
对于每个右端点 我们加入所有新增的边 维护最大生成树
询问么 就是n-生成树中编号大于等于左端点 因为这样的边会把两个联通块连在一起
考虑询问按右端点排序
对于一条边 边的权值定义为较小的一端的编号
那么显然权值大的边更有利
对于每个右端点 我们加入所有新增的边 维护最大生成树
询问么 就是n-生成树中编号大于等于左端点 因为这样的边会把两个联通块连在一起
#include<cstdio> #include<cstdlib> #include<algorithm> #include<stack> using namespace std; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline bool read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; else if (c==EOF) return 0; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; return 1; } const int N=100005; namespace BIT{ int c ,maxn; inline void init(int n){ maxn=n; for (int i=1;i<=n;i++) c[i]=0; } inline void add(int x,int r){ for (int i=x;i<=maxn;i+=i&-i) c[i]+=r; } inline int sum(int x){ int ret=0; for (int i=x;i;i-=i&-i) ret+=c[i]; return ret; } inline int sum(int l,int r){ return sum(r)-sum(l-1); } } int us[N*2],vs[N*2],ws[N*3]; inline int Min(int a,int b){ return ws[a]<ws[b]?a:b; } struct node{ node *f,*ch[2]; int idx,v; bool rev; bool isr() { return !f || (f->ch[0]!=this && f->ch[1]!=this); } bool dir() { return f->ch[1]==this; } void setc(node *c,int d) { ch[d]=c; if (c) c->f=this; } void push() { if (rev) { swap(ch[0],ch[1]); if(ch[0])ch[0]->rev^=1; if(ch[1])ch[1]->rev^=1; rev=0;} } void upd() { v=idx; if(ch[0])v=Min(v,ch[0]->v); if(ch[1])v=Min(v,ch[1]->v); } }pool[N*3]; inline void rot(node *x){ node *p=x->f; bool d=x->dir(); if (!p->isr()) p->f->setc(x,p->dir()); else x->f=p->f; p->setc(x->ch[d^1],d); x->setc(p,d^1); p->upd(); } stack<node*> sta; inline void splay(node *x){ node *q=x; for (;!q->isr();q=q->f) sta.push(q); sta.push(q); while (!sta.empty()) sta.top()->push(),sta.pop(); while (!x->isr()) if (x->f->isr()) rot(x); else if (x->dir()==x->f->dir()) rot(x->f),rot(x); else rot(x),rot(x); x->upd(); } void expose(node *x){ for (node *q=NULL;x;q=x,x=x->f) splay(x),x->ch[1]=q,x->upd(); } void exert(node *x){ expose(x); splay(x); x->rev^=1; } void link(node *x,node *y) { exert(y); y->f=x; } void cut(node *x,node *y) { exert(x); expose(y); splay(y); y->ch[0]=x->f=NULL; y->upd(); } node *frt(node *x){ expose(x),splay(x); for (;x->push(),x->ch[0];x=x->ch[0]); return x; } int query(node *x,node *y){ exert(x); expose(y); splay(y); return y->v; } int n,m; struct abcd{ int l,r,idx; bool operator < (const abcd &B) const{ return r<B.r; } }eve[N*2]; int tot,ans ; inline void addedge(int i){ if (frt(pool+m+us[i])==frt(pool+m+vs[i])){ int p=query(pool+m+us[i],pool+m+vs[i]); if (ws[p]<ws[i]){ cut(pool+p,pool+m+us[p]),cut(pool+p,pool+m+vs[p]); BIT::add(ws[p],-1); link(pool+i,pool+m+us[i]),link(pool+i,pool+m+vs[i]); BIT::add(ws[i],1); } }else link(pool+i,pool+m+us[i]),link(pool+i,pool+m+vs[i]),BIT::add(ws[i],1); } inline int query(int i){ return n-BIT::sum(eve[i].l,eve[i].r); } int main(){ freopen("t.in","r",stdin); freopen("t.out","w",stdout); while (read(n)&&read(m)&&read(tot)){ for (int i=1;i<=m;i++) { read(eve[i].l),read(eve[i].r); if (eve[i].l>eve[i].r) swap(eve[i].l,eve[i].r); } sort(eve+1,eve+m+1); for (int i=1;i<=m;i++) us[i]=ws[i]=eve[i].l,vs[i]=eve[i].r; for (int i=m+1;i<=m+n;i++) ws[i]=1<<30; for (int i=1;i<=m+n;i++) pool[i].idx=pool[i].v=i,pool[i].rev=0,pool[i].f=pool[i].ch[0]=pool[i].ch[1]=NULL; for (int i=1;i<=tot;i++) read(eve[i].l),read(eve[i].r),eve[i].idx=i; sort(eve+1,eve+tot+1); int pnt1=1,pnt2=1; BIT::init(n); for (int i=1;i<=n;i++){ while (pnt1<=m && vs[pnt1]==i) addedge(pnt1),pnt1++; while (pnt2<=tot && eve[pnt2].r==i) ans[eve[pnt2].idx]=query(pnt2),pnt2++; } for (int i=1;i<=tot;i++) printf("%d\n",ans[i]); } return 0; }
相关文章推荐
- HDU 5333 Undirected Graph 离线 LCT维护最大生成树+树状数组
- HDU 5333 [LCT][树状数组]
- 二维树状数组 hdu 1892
- [hdu]1394 Minimum Inversion Number -- 暴力求逆序、树状数组求逆序、线段树求逆序、归并排序求逆序
- hdu 2492【树状数组】
- (树状数组) hdu 1166 敌兵布阵
- HDU 1556 Color the ball 很典型的更新区间查找点的题(线段树树状数组两种解法)
- http://acm.hdu.edu.cn/showproblem.php?pid=3015 树状数组
- HDU_1541 Stars(树状数组)
- hdu 1394 树状数组版!!!
- hdu 3584 三维树状数组 很烦的说
- HDU 2852 树状数组解决第K小数 附线段树解法
- hdu 1166 树状数组 入门题
- HDU 1166 敌兵布阵【树状数组】
- HDU 1166 敌兵布阵【树状数组】
- hdu 3015【树状数组】
- hdu 1892 See you~ 二维树状数组
- HDU 3525(树状数组求解LCS)
- hdu 1166 敌兵布阵 (树状数组)
- HDU 2642 Stars 简单二维树状数组应用