HDU 5398 GCD TREE LCT维护贪心
来源:互联网 发布:电脑mac地址查询方法 编辑:程序博客网 时间:2024/04/26 13:57
HDU 5398 GCD TREE LCT维护贪心
题目链接:传送门
题意:找出一颗1~n的最大生成树,边的权值为连接节点的GCD。
思路:贪心的考虑每条边的权值一定为较小的点的值,将1~n从大到小加入到生成树中,向其因子连边,用LCT维护一下最大生成树就好了。
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <vector>using namespace std;//加边维护最大生成树int now_ans;const int INF=10000010;namespace LCT{ const int INF=1e9; #define NIL mem const int max_n=300100; const int mpool=300100; struct Node { int val; int sum; int pos,mpos; bool root,rev; int l,r; Node *lch,*rch,*fa; Node(){ mpos=pos=0; sum=val=0; } Node(int _val,int _pos,Node *_lch,Node* _rch,Node *_fa) :val(_val),pos(_pos),lch(_lch),rch(_rch),fa(_fa){ mpos=pos; sum=val; root=true; rev=false; } }mem[mpool],*pool[mpool]; struct link_cut_tree{ Node *node[3000000]; int tp; Node *stk[max_n]; int n,tot; int max1(int a,int b){ if(node[a]->val<node[b]->val){ return a; } else { return b; } } void init(){ NIL->val=INF; NIL->sum=0;; node[0]=NIL; NIL->lch=NIL->rch=NIL->fa=NIL; NIL->pos=NIL->mpos=0; tot=0; for(int i=1;i<max_n;i++){ pool[tot++]=mem+i; } } void build(int _n){ n=_n; tp=n+1; for(int i=1;i<=n;i++){ node[i]=new(pool[--tot])Node(0,0,NIL,NIL,NIL); } } void apy(int num,int val,int l,int r){ node[num]=new(pool[--tot])Node(val,num,NIL,NIL,NIL); node[num]->l=l,node[num]->r=r; } void reverse(Node *t){ if(t==NIL)return; t->rev^=1; swap(t->rch,t->lch); } void pushdown(Node *t){ if(t==NIL)return; if(t->rev){ t->rev=false; reverse(t->lch); reverse(t->rch); } } void update(Node *t){ if(t==NIL)return; t->mpos=max1(t->pos,max1(t->lch->mpos,t->rch->mpos)); t->sum=t->lch->sum+t->rch->sum+t->val; } void zig(Node *t){ Node *f=t->fa,*c=t->rch; if(f->root)t->root=true,f->root=false; else (f->fa->lch==f?f->fa->lch:f->fa->rch)=t; t->fa=f->fa,t->rch=f,f->lch=c,c->fa=f,f->fa=t; update(f); } void zag(Node *t){ Node *f=t->fa,*c=t->lch; if(f->root)t->root=true,f->root=false; else (f->fa->lch==f?f->fa->lch:f->fa->rch)=t; t->fa=f->fa,t->lch=f,f->rch=c,c->fa=f,f->fa=t; update(f); } void splay(Node *t){ Node *p=t; int top=0; stk[top]=t; while(!p->root){ stk[++top]=p->fa; p=p->fa; } while(top>=0){ pushdown(stk[top--]); } while(!t->root){ if(t->fa->root){ if(t->fa->lch==t)zig(t); else zag(t); } else { if(t->fa->fa->lch==t->fa){ if(t->fa->lch==t)zig(t->fa),zig(t); else zag(t),zig(t); } else { if(t->fa->lch==t)zig(t),zag(t); else zag(t->fa),zag(t); } } } update(t); } void evert(Node *t){ t=expose(t); reverse(t); } Node * expose(Node *t){ Node *p=t,*q=NIL; while(p!=NIL){ splay(p); p->rch->root=true; p->rch=q; q->root=false; q=p; update(p); p=p->fa; } return q; } void cut(int a,int b){ evert(node[b]); expose(node[a]); splay(node[a]); node[a]->lch->fa=NIL; node[a]->lch->root=true; node[a]->lch=NIL; return; } void erase(int a){ int l=node[a]->l,r=node[a]->r; cut(a,l); cut(a,r); pool[tot++]=node[a]; return; } Node * getroot(Node *t){ t=expose(t); while(1){ if(t->lch!=NIL)t=t->lch; else return t; } } void link(int a,int b){ if(getroot(node[a])==getroot(node[b])){ cut_it(a,b); } evert(node[b]); splay(node[b]); node[b]->fa=node[a]; expose(node[b]); } void Link(int a,int b){ apy(++tp,b,a,b); link(tp,a); link(b,tp); } void cut_it(int a,int b){ expose(node[a]); Node *p=node[b],*q=NIL; int tp; while(p!=NIL){ splay(p); if(p->fa==NIL){ tp=max1(p->pos,max1(p->rch->mpos,q->mpos)); } p->rch->root=true; p->rch=q; p->rch->root=false; update(p); q=p; p=p->fa; } now_ans-=node[tp]->val; erase(tp); } void dfs(Node *t){ if(t==NIL)return ; pushdown(t); dfs(t->lch); printf("%d %d\n",t->pos,t->val); dfs(t->rch); } };}LCT::link_cut_tree T;const int N=100100;vector<int> fac[N];void prepare(){ for(int i=1;i<N;i++){ for(int j=i+i;j<N;j+=i){ fac[j].push_back(i); } }}int ans[N];int main(){ prepare(); T.init(); T.build(N-1); now_ans=0; for(int i=1;i<N;i++){ for(int j=0;j<fac[i].size();j++){ T.Link(i,fac[i][j]); now_ans+=fac[i][j]; } ans[i]=now_ans; }// return 0; int n; while(scanf("%d",&n)!=EOF){ printf("%d\n",ans[n]); } return 0;}
0 0
- HDU 5398 GCD TREE LCT维护贪心
- hdu 5398:GCD Tree lct
- LCT(GCD Tree,HDU 5398)
- [LCT 动态最大生成树] HDU 5398 GCD Tree
- 【LCT维护最大生成树】[HDU5389]GCD Tree
- hdu 5398 GCD Tree 2015多校联合训练赛#9 LCT,动态生成树
- HDU 5398 GCD Tree
- hdu 5398 GCD Tree
- hdu 5002 Tree (LCT)
- hdu 5002 Tree (LCT)
- [GCD最小生成树 LCT] HDU5398 .GCD TREE
- HDU 5458(Stability-LCT维护连通图2点间割边个数)
- HDU 5726 GCD (线段树维护区间gcd)
- LCT维护问题
- Hdu 4010 Query on The Trees lct link-cut tree
- Hdu 4718 The LCIS on the Tree 动态树 LCT
- HDU 5293 TREE CHAIN PROBLEM LCT+树形DP
- HDU 4010 Query on the tree LCT模板题
- Android学习系列之(三)Activity的基本使用
- poj 3468 A Simple Problem with Integers(线段树区间修改)
- Linux下32位和64位不同数据类型字段长度
- HDU5411CRB and Puzzle(矩阵快速幂)
- 626 intersection set
- HDU 5398 GCD TREE LCT维护贪心
- [C++] String to Integer (atoi)
- 慎用USES_CONVERSION
- IOS_下拉刷新
- WPF 自定义RadioButton ,仿照360
- json数据和数组的转换,以及访问
- JDK API 在线文档
- C语言优先级总结
- 打开虚拟硬盘 失败