GCD Tree

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 415    Accepted Submission(s): 172

Problem Description
Teacher Mai has a graph with n vertices numbered from 1 to n. For every edge(u,v), the weight is gcd(u,v). (gcd(u,v) means the greatest common divisor of number uand v).

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.

 
Input
There are multiple test cases(about 105).

For each test case, there is only one line contains one number n(1≤n≤105).

 
Output
For each test case, print the answer.
 
Sample Input
1
2
3
4
5
 
Sample Output
0
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的更多相关文章

  1. hdu 5002 (动态树lct)

    Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  2. hdu 5314 动态树

    Happy King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  3. 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 ...

  4. 动态树LCT小结

    最开始看动态树不知道找了多少资料,总感觉不能完全理解.但其实理解了就是那么一回事...动态树在某种意思上来说跟树链剖分很相似,都是为了解决序列问题,树链剖分由于树的形态是不变的,所以可以通过预处理节点 ...

  5. bzoj2049-洞穴勘测(动态树lct模板题)

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  6. [模板] 动态树/LCT

    简介 LCT是一种数据结构, 可以维护树的动态加边, 删边, 维护链上信息(满足结合律), 单次操作时间复杂度 \(O(\log n)\).(不会证) 思想类似树链剖分, 因为splay可以换根, 用 ...

  7. 动态树LCT(Link-cut-tree)总结+模板题+各种题目

    一.理解LCT的工作原理 先看一道例题: 让你维护一棵给定的树,需要支持下面两种操作: Change x val:  令x点的点权变为val Query x y:  计算x,y之间的唯一的最短路径的点 ...

  8. SPOJ OTOCI 动态树 LCT

    SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...

  9. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (动态树LCT)

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2843  Solved: 1519[Submi ...

随机推荐

  1. find命令之(-atime,-ctime,-mtime)

    关于find命令,以拙见总结如下: >>>定义: find命令用来在指定目录下查找文件. 任何位于参数之前的字符串都将被视为欲查找的目录名.如果使用该命令时,不设置任何参数,则fin ...

  2. Swift 2.2 的新特性

    导读:本文来自SwiftGG翻译组,作者@walkingway基于苹果Swift官方博客中Ted Kremenek所撰写的"Swift 2.2 Released!"文章进行了关于S ...

  3. JAVA_SE基础——50.接口关系下的多态

    接口关系下的多态和继承关系下的多态 相差无几,应该更简单些~ 多态: 父类的引用类型变量指向了子类的对象或者是接口类型的引用类型变量指向了接口实现类 的对象. 实现关系下的多态: 接口  变量  = ...

  4. Nginx配置小结

    前两天区听了一堂Nginx的课,然后翻了一下自己之前的Nginx的笔记,做了一个简单的小结. 全局变量 $args : 这个变量等于请求行中的参数,同$query_string $content_le ...

  5. js解决IE8不支持html5,css3的问题(respond.js 的使用注意)

    IE8.0及以下不支持html5,css3的解析.目前为止IE8以下的版本使用率在10%左右,网站还是有必要兼容的. 1,在你的所有css最后判断引入两个js文件. html5.js  是用来让ie8 ...

  6. 第五章 JavaScript对象及初识面向对象

    第五章   JavaScript对象及初识面向对象 一.对象 在JavaScript中,所有事物都是对象,如字符串.数值.数组.函数等. 在JavaScript对象分为内置对象和自定义对象,要处理一些 ...

  7. 静态链表的C实现(基于数据结构 严蔚敏)

    静态链表是利用一维数组实现逻辑上的单链表结构,结点的逻辑上相邻但物理位置上不一定相邻,因为内存分配上是一次性的,故称为静态. 特点: 预先需要一片连续的存储空间: 非随机存取: 无现成的"内 ...

  8. JS 上传图片时实现预览

    网页中一张图片可以这样显示: <img src="http://www.letuknowit.com/images/wg.png"/>也可以这样显示:<img s ...

  9. 聊一聊C#的Equals()和GetHashCode()方法

    博客创建一年多,还是第一次写博文,有什么不对的地方还请多多指教. 关于这次写的内容可以说是老生长谈,百度一搜一大堆.大神可自行绕路. 最近在看Jeffrey Richter的CLR Via C#,在看 ...

  10. 算法题丨4Sum

    描述 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...