[GCD最小生成树 LCT] HDU5398 .GCD TREE
2017-10-23 15:06
309 查看
可以发现只要保留边 (i,j) 其中 i 整除 j 的边就行了
用LCT来维护最大生成树就可以了
用LCT来维护最大生成树就可以了
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int N=1500010; int n,cnt,m; struct iedge{ int x,y; friend bool operator <(iedge a,iedge b){ return a.x<b.x; } }e ; struct inode{ inode *ch[2],*f; int v,imax; bool rev; }a ; int lst; ll cur,ans[100010]; void PutAns(ll x){ if(x>=10) PutAns(x/10); putchar(x%10+'0'); } int fa ; int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); } inline int isr(inode *x){ return x->f && x->f->ch[1]==x; } inline int isl(inode *x){ return !x->f || (x->f->ch[0]!=x && x->f->ch[1]!=x); } inline void Up(inode *x){ if(!x) return ; x->imax=x->v; if(x->ch[0] && e[x->ch[0]->imax].y<e[x->imax].y) x->imax=x->ch[0]->imax; if(x->ch[1] && e[x->ch[1]->imax].y<e[x->imax].y) x->imax=x->ch[1]->imax; } inline void Push(inode *x){ if(!x || !x->rev) return ; swap(x->ch[0],x->ch[1]); if(x->ch[0]) x->ch[0]->rev^=1; if(x->ch[1]) x->ch[1]->rev^=1; x->rev=0; } inline void rot(inode *x){ inode *y=x->f,*z=y->f; int wh=isr(x); if(!isl(y)) z->ch[isr(y)]=x; x->f=z; if(y->ch[wh]=x->ch[wh^1]) y->ch[wh]->f=y; (x->ch[wh^1]=y)->f=x; Up(y); Up(x); } void PushTop(inode *x){ if(!isl(x)) PushTop(x->f); Push(x); } inline void splay(inode *x){ PushTop(x); for(;!isl(x);rot(x)) if(!isl(x->f)) rot(isr(x)^isr(x->f)?x:x->f); } inline void access(inode *x){ for(inode *t=0;x;x=x->f) splay(x),x->ch[0]=t,t=x,Up(x); } inline void reverse(inode *x){ access(x); splay(x); x->rev^=1; } inline void link(inode *x,inode *y){ reverse(x); x->f=y; access(x); } inline void cut(inode *x,inode *y){ reverse(x); access(y); splay(y); x->f=y->ch[0]=0; Up(y); } inline int Query(inode *x,inode *y){ reverse(x); access(y); splay(y); return y->imax; } inline void Addedge(iedge c,int x){ a[m+x].imax=a[m+x].v=x; if(find(c.x)!=find(c.y)){ fa[find(c.x)]=find(c.y); link(a+c.x,a+m+x); link(a+c.y,a+m+x); cur+=e[x].y; return ; } int imin=Query(a+c.x,a+c.y); if(e[imin].y>=e[x].y) return ; cur+=e[x].y-e[imin].y; cut(a+e[imin].x,a+m+imin); cut(a+e[imin].y,a+m+imin); link(a+c.x,a+m+x); link(a+c.y,a+m+x); } int main(){ m=100000; e[0].y=1<<30; for(int i=1;i<=m;i++) for(int j=i+i;j<=m;j+=i) e[++cnt]=(iedge){j,i}; sort(e+1,e+1+cnt); int j=0; for(int i=1;i<=m;i++) fa[i]=i; while(~scanf("%d",&n)){ for(int i=lst+1;i<=n;i++){ while(e[j+1].x<=i && j<cnt) Addedge(e[j+1],j+1),j++; ans[i]=cur; } lst=max(lst,n); PutAns(ans ); putchar('\n'); } return 0; }
相关文章推荐
- hdu 5398 GCD Tree 2015多校联合训练赛#9 LCT,动态生成树
- hdu5398 GCD Tree(lct)
- HDU 2489 Minimal Ratio Tree(dfs枚举+最小生成树)
- 最小生成树Minimum Spanning Tree
- 2594: [Wc2006]水管局长数据加强版 LCT维护最小生成树+hash
- bzoj 1977: [BeiJing2010组队]次小生成树 Tree 最小生成树+倍增
- HDU 2489 Minimal Ratio Tree【最小生成树】
- Geeks : Kruskal’s Minimum Spanning Tree Algorithm 最小生成树
- 第十五章 GRL_2_A:Minimum Spanning Tree 最小生成树
- hdu 2682 Tree 最小生成树
- HDU2682 Tree 最小生成树
- 说说最小生成树(Minimum Spanning Tree)
- hdu2682 TREE 素数,最小生成树
- poj 1308 Is It A Tree? (最小生成树)
- [BZOJ2654]tree 最小生成树+贪心
- bzoj 2654: tree 二分+最小生成树
- bzoj 2594 水管局长 | LCT | 最小生成树
- [bzoj2654][最小生成树][二分]tree
- bzoj 3669 lct维护最小生成树
- 【BZOJ】1016 生成树计数 最小生成树 Maxtrix-Tree定理 生成树计数 搜索