博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【LCT维护最大生成树】[HDU5389]GCD Tree
阅读量:4334 次
发布时间:2019-06-07

本文共 3215 字,大约阅读时间需要 10 分钟。

分析:由于wt(u,v)=gcd(u,v),所以我们枚举gcd,而且只尝试连接gcd和它的倍数,也就是我们尝试连接(i,j),仅当j是i的倍数,至于于为什么,我也不知道。
用LCT维护最大生成树,每次连接一条边时,必定形成一个环,删除这个环中最小边即可。

#include
#include
#include
using namespace std;#define MAXN 100000#define INF 0x7fffffffint ans[MAXN+10],T,n;vector
fac[MAXN];void Read(int &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; } exit(0);}struct node{ int val,lgcd; bool pre,tag; node *ch[2],*fa;}splay_tree[MAXN+10];inline void push_down(node *p){ if(p->tag){ p->tag=0; if(p->ch[0]) p->ch[0]->tag^=1; if(p->ch[1]) p->ch[1]->tag^=1; swap(p->ch[0],p->ch[1]); }}inline int Get_lgcd(node *p){ return p?p->lgcd:INF;}inline void update(node *p){ p->lgcd=min(min(Get_lgcd(p->ch[0]),Get_lgcd(p->ch[1])),p->val);}void push_up(node *p){ if(p->pre) push_up(p->fa); push_down(p);}void Rotate(node *x,int d){ node *y=x->fa; if(y->pre) y->fa->ch[y==y->fa->ch[1]]=x; x->fa=y->fa; if(x->ch[d]) x->ch[d]->fa=y; y->ch[!d]=x->ch[d]; x->ch[d]=y; y->fa=x; swap(x->pre,y->pre); update(y);}void splay(node *x){ node *y,*z; push_up(x); while(x->pre){ y=x->fa; z=y->fa; if(!y->pre){ if(x==y->ch[0]) Rotate(x,1); else Rotate(x,0); } else if(y==z->ch[0]) if(x==y->ch[0]){ Rotate(y,1); Rotate(x,1); } else{ Rotate(x,0); Rotate(x,1); } else if(x==y->ch[1]){ Rotate(y,0); Rotate(x,0); } else{ Rotate(x,1); Rotate(x,0); } } update(x);}void access(node *x){ node *y=0,*z=x; while(x){ splay(x); if(x->ch[1]) x->ch[1]->pre=0; x->ch[1]=y; if(y) y->pre=1; y=x; x=x->fa; } splay(z);}inline void link(node *x,node *y){ access(x); access(y); y->pre=y->tag=1; x->ch[1]=y; y->fa=x; update(x);}void prepare(){ int i,j,d,nans=0,d2; node *x,*y,*z; vector
::iterator k; splay_tree[1].val=splay_tree[1].lgcd=1; for(i=2;i<=MAXN;i++){ splay_tree[i].val=splay_tree[i].lgcd=i; link(splay_tree+i,splay_tree+1); nans++; for(j=i+i;j<=MAXN;j+=i) fac[j].push_back(i); for(k=fac[i].begin();k!=fac[i].end();k++){ d=*k; x=splay_tree+i; y=splay_tree+d; access(x); x->tag=1; access(y); d2=y->lgcd; if(d2
ch[0]){ z->ch[0]->fa=0; z->ch[0]->pre=0; z->ch[0]=0; } else{ z->ch[1]->fa=0; z->ch[1]->pre=0; z->ch[1]=0; } update(splay_tree+d2); link(x,y); } } ans[i]=nans; }}int main(){ prepare(); while(1){ Read(n); printf("%d\n",ans[n]); }}

转载于:https://www.cnblogs.com/outerform/p/5921904.html

你可能感兴趣的文章
Json
查看>>
poj1236Network of Schools Tarjan裸题
查看>>
项目管理过程
查看>>
泛型使用
查看>>
Employment Planning[HDU1158]
查看>>
hdu2089:不要62(基础数位dp)
查看>>
Tools
查看>>
JS获取第二个横杠后面的内容
查看>>
excel 导入MYSQL
查看>>
P3038 [USACO11DEC]牧草种植Grass Planting
查看>>
23 个最有吸引力和免费的Flash图像轮廓
查看>>
给label添加点击事件
查看>>
eterna 第一个案例
查看>>
新部署到服务器 报 The requested URL /home/profession was not found on this server. 错误
查看>>
hadoop从非HA转到NAMENODE HA时需要注意的一个问题
查看>>
KnockoutJs学习笔记(十一)
查看>>
访问修饰符public、private、protect、default范围
查看>>
jQuery实现布局高宽自适应
查看>>
《学习》10函数的建立与使用
查看>>
去除TB二合一页面弹窗
查看>>