hdu 5398 动态树LCT
GCD Tree
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 415 Accepted Submission(s): 172
You need to find a subset of the edges that forms a tree that includes every vertex, where the total weight of all the edges in the tree is maximized. Print the total weight of these edges.
For each test case, there is only one line contains one number n(1≤n≤105).
2
3
4
5
1
2
4
5
/*
hdu 5398 动态树LCT problem:
给你n个点,让你构成一棵树,边的权值为端点的最大公约数. 求树的最大边权和 solve:
枚举所有点,然后贪心的思想.如果n-1个点构成了一个最大的生成树,那么加入第n个点时我们应尽可能把它往
自己的约数上连(大->小).这样的话就在连接第二个约数的时候就会构成环,所以需要将 当前点-->当前约数点的链上
断开最小的一条边.
所以可以枚举 点和其约数,然后利用LCT维护链上面的最小边. 就这个想了很久,不知道应该吧边权保存在哪个端点
比较好,总感觉会有矛盾 = =||. 结果发现完全可以弄个点来替代边,将点上的值初始化无限大就行了T_T,好2... hhh-2016-08-21 16:43:04
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#define lson ch[0]
#define rson ch[1]
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
using namespace std;
const int maxn = 100100;
const int INF = 0x3f3f3f3f; struct Node* null;
struct Node
{
Node* ch[2] ;
Node* fa;
int Min;
Node* Minnode;
int Size,lpos,rpos ;
int rev;
void newnode(int v)
{
Min = v;
Size = 1 ;
Minnode = this;
lpos = rpos = 0;
fa = ch[0] = ch[1] = null ;
rev = 0;
}
void ini()
{
Min = INF;
Size = 1 ;
Minnode = this;
lpos = rpos = 0;
fa = ch[0] = ch[1] = null ;
rev = 0;
}
void update_rev()
{
if(this == null)
return ;
swap(ch[0],ch[1]);
rev ^= 1;
} void push_up ()
{
Minnode = this;
if(ch[0] && ch[0]->Minnode->Min < Minnode->Min)
Minnode = ch[0]->Minnode;
if(ch[1] && ch[1]->Minnode->Min < Minnode->Min)
Minnode = ch[1]->Minnode;
} void push_down()
{
if(rev)
{
ch[0]->update_rev();
ch[1]->update_rev();
rev = 0;
}
} void link_child ( Node* o , int d )
{
ch[d] = o ;
o->fa = this ;
} int isroot()
{
return fa == null || this != fa->ch[0] && this != fa->ch[1] ;
}
void sign_down ()
{
if ( !isroot () ) fa->sign_down () ;
push_down () ;
}
void Rotate ( int d )
{
Node* p = fa ;
Node* gp = fa->fa ;
p->link_child ( ch[d] , !d ) ;
if ( !p->isroot () )
{
if ( gp->ch[0] == p ) gp->link_child ( this , 0 ) ;
else gp->link_child ( this , 1 ) ;
}
else fa = gp ;
link_child ( p , d ) ;
p->push_up () ;
} void splay ()
{
sign_down () ;
while ( !isroot () )
{
if ( fa->isroot () )
{
this == fa->ch[0] ? Rotate ( 1 ) : Rotate ( 0 ) ;
}
else
{
if ( fa == fa->fa->ch[0] )
{
this == fa->ch[0] ? fa->Rotate ( 1 ) : Rotate ( 0 ) ;
Rotate ( 1 ) ;
}
else
{
this == fa->ch[1] ? fa->Rotate ( 0 ) : Rotate ( 1 ) ;
Rotate ( 0 ) ;
}
}
}
push_up () ;
} void access()
{
Node* o = this ;
Node* x = null ;
while ( o != null )
{
o->splay () ;
o->link_child ( x , 1 ) ;
o->push_up () ;
x = o ;
o = o->fa ;
}
splay () ;
} void make_root()
{
access();
update_rev();
} void cut()
{
access();
ch[0]->fa = null;
ch[0] = null;
push_up();
}
Node* find_root ()
{
access () ;
Node* o = this ;
while ( o->ch[0] != null )
{
o->push_down () ;
o = o->ch[0] ;
}
return o ;
}
void cut(Node* to)
{
to->make_root();
cut();
} void link(Node* to)
{
to->make_root();
to->fa = this;
}
Node* query(Node* to)
{
to->make_root();
access();
return Minnode;
}
};
Node memory_pool[maxn*2];
Node* now;
Node* node[maxn]; void Clear()
{
now = memory_pool;
now->newnode(INF);
null = now ++;
null->Size = 0;
}
int dp[maxn];
vector<int > vec[maxn]; void init()
{
Clear();
for(int i = 100000; i >= 1; i--)
{
now->newnode(INF);
node[i] = now++;
for(int j = i+i; j <= 100000; j+=i)
{
vec[j].push_back(i);
}
}
int tans = 0;
dp[1] = 0;
now->newnode(INF),node[1] = now++;
for(int i =2; i <= 100000; i++)
{
// cout << "number:" << i<<endl;
now->newnode(vec[i][0]);
Node *tp = now++;
tp->link(node[i]);
tp->link(node[vec[i][0]]);
tp->lpos = i,tp->rpos = vec[i][0];
tans += vec[i][0];
// cout << tp->lpos <<" " <<tp->rpos <<" " <<tans <<endl;
for(int j = 1;j < vec[i].size();j++)
{
int to = vec[i][j];
// cout <<"to "<<to <<endl; Node* tMin = node[to]->query(node[i]);
// cout <<"Min:" << tMin->lpos <<" " <<tMin->rpos <<" "<<tMin->Min <<endl;
if(tMin->Min < to)
{
tans -= tMin->Min;
tMin->cut(node[tMin->lpos]);
// cout <<"cut1 ";
tMin->cut(node[tMin->rpos]);
// cout << "cut2" <<endl;
tMin->ini();
tMin->Min = to,tMin->lpos = i,tMin->rpos = to;
// cout << i <<" " <<to<<endl; tMin->link(node[i]);
// cout <<"link1 ";
tMin->link(node[to]);
// cout << "link2" <<endl;
tans += to;
}
}
dp[i] = tans ;
}
} int main()
{ // freopen("in.txt","r",stdin);
init();
int n;
while( scanf("%d",&n) !=EOF)
{
printf("%d\n",dp[n]);
}
return 0;
}
hdu 5398 动态树LCT的更多相关文章
- hdu 5002 (动态树lct)
Tree Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- hdu 5314 动态树
Happy King Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Tot ...
- HDU 4718 The LCIS on the Tree (动态树LCT)
The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- 动态树LCT小结
最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...
- bzoj2049-洞穴勘测(动态树lct模板题)
Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...
- [模板] 动态树/LCT
简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...
- 动态树LCT(Link-cut-tree)总结+模板题+各种题目
一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val: 令x点的点权变为val Query x y: 计算x,y之间的唯一的最短路径的点 ...
- SPOJ OTOCI 动态树 LCT
SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2843 Solved: 1519[Submi ...
随机推荐
- 简单的C语言编译器--语法分析器
语法分析算是最难的一部分了.总而言之,语法分析就是先设计一系列语法,然后再用设计好的语法去归约词法分析中的结果.最后将归约过程打印出来,或者生成抽象语法树. 1. 设计文法 以下是我的文法(引入的 ...
- 2017-2018-1 我爱学Java 第四五周 作业
<打地鼠>Android游戏--需求规格说明书 工作流程 组员分工及工作量比例 <需求规格说明书>的码云链接 总结与反思 参考资料 工作流程 小组成员预先参考蓝墨云班课第八周中 ...
- PID控制示例C编程
typedef struct PID_zhs { double P,I,D;//P.I.D系数 float curError;//当前误差 float lastError;//上次误差 float p ...
- 几款有用的AndroidStudio插件
1.Android Parcelable code generator 顾名思义,这是个生成实现了Parcelable接口的代码的插件. 在你的类中,按下alt + insert键弹出插入代码的上下文 ...
- Webview之H5页面调用android的图库及文件管理
h5页面打开图片管理器 一般页面在pc打开文件管理器是用 type="file"的代码,可是这在android的webview是无效的,必须为webview设定WebChromeC ...
- PostMan 调用WCF Rest服务
问题描述: 现在有已有的WCF服务,但是ajax是不能请求到这个服务的: 需要把WCF转成WCF REST 的风格. 以下是从WCF转 WCF REST的步骤 1.首先在接口定义的地方加上 请求 We ...
- jQuery 写的textarea输入字数限制
//先判断浏览器是不是万恶的IE var bind_name = 'input';//默认事件 if (navigator.userAgent.indexOf(" ...
- Delphi Web开发连载 --ThinkDelphi (序)
如果把Delphi比作男人,那他曾经独步天下,笑傲江湖过: 如果把Delphi比作女子,那她曾经貌美如花,倾国倾城过! 但那只是历史,那只是曾经, 弹指一挥间,Delphi却似乎英雄迟暮,美人已老.. ...
- zuul入门(1)zuul 的概念和原理
一.zuul是什么 zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用. Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架. ...
- GIT入门笔记(20)- git 开发提交代码过程梳理
git开发提交流程新项目开发,可以直接往master上提交老项目维护,可以在分支上修改提交,多次add和commit之后,也可以用pull合并主干和本地master,解决冲突后再push 1.检出代码 ...