转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

GCD Tree

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

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 u and 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

LCT维护最大生成树,从小到大不断加入数的时候,先和它最大的约数连边,这样就已经变成一棵树了,然后从大到小依次查询其他因子,每次查找到这个数的路径上的最小值,然后砍断这条边,把i和这次查询的因子相连,因为砍掉的边的权值一定不会超过新加的边,所以每次都在增大,这样能够保证最优

队友随手过了这题。23333333

我的写法是把边权搞成一个点,其实不这样也行,找出最小的点,然后看一下在路径上和这个点相邻的点。

 /**
* code generated by JHelper
* More info: https://github.com/AlexeyDmitriev/JHelper
* @author xyiyy @https://github.com/xyiyy
*/ #include <iostream>
#include <fstream> //#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/
//#####################
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype> using namespace std;
#define XINF INT_MAX
#define INF 0x3FFFFFFF
#define mp(X, Y) make_pair(X,Y)
#define pb(X) push_back(X)
#define rep(X, N) for(int X=0;X<N;X++)
#define rep2(X, L, R) for(int X=L;X<=R;X++)
#define dep(X, R, L) for(int X=R;X>=L;X--)
#define clr(A, X) memset(A,X,sizeof(A))
#define IT iterator
#define ALL(X) (X).begin(),(X).end()
#define PQ std::priority_queue
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<PII> VII;
typedef vector<int> VI; const int MAXN = ;
int pre[MAXN<<], ch[MAXN<<][], rev[MAXN<<];
int key[MAXN<<];
int lx[MAXN<<],rx[MAXN<<];
int mx[MAXN<<]; void push_down(int r) {
if(!r)return;
if (rev[r]) {
rev[ch[r][]] ^= ;
rev[ch[r][]] ^= ;
swap(ch[r][], ch[r][]);
rev[r] ^= ;
}
} void push_up(int x) {
int l = ch[x][],r = ch[x][];
mx[x] = x;
if(key[mx[l]]<key[mx[x]])mx[x] = mx[l];
if(key[mx[r]]<key[mx[x]])mx[x] = mx[r];
} void rotate(int x, int d) {
const int y = pre[x];
ch[y][!d] = ch[x][d];
if (ch[x][d])pre[ch[x][d]] = y;
pre[x] = pre[y];
if (ch[pre[y]][] == y)ch[pre[x]][] = x;
else if (ch[pre[y]][] == y)ch[pre[x]][] = x;
pre[y] = x;
ch[x][d] = y;
push_up(y);
} bool _splay_parent(int x,int &y){
return (y = pre[x])!= && (ch[y][] == x || ch[y][] == x);
} void splay(int x,int goal) {
push_down(x);
for (int y,z;_splay_parent(x,y);) {
//cout<<x<<" "<<y<<endl;
if(_splay_parent(y,z)){
push_down(z);push_down(y);push_down(x);
int d = y == ch[z][];
if(x == ch[y][d])rotate(x,d^),rotate(x,d);
else rotate(y,d),rotate(x,d);
}else {
push_down(y),push_down(x);
rotate(x, x == ch[y][]);break;
}
}
push_up(x);
} int access(int u) {
int v = ;
for (; u; u = pre[u]) {
splay(u,);
ch[u][] = v;
push_up(v = u);
}
return v;
} void makeroot(int x) {
rev[access(x)] ^= ;
splay(x,);
} void link(int x, int y) {
makeroot(x);
pre[x] = y;
} void cut(int x, int y) {
makeroot(x);
access(y);
splay(y,);
pre[ch[y][]] = ;
ch[y][] = ;
push_up(y);
} void Init(int n) {
for (int i = ; i < n; i++) {
pre[i] = ch[i][] = ch[i][] = ;
key[i] = INF;
mx[i] = ;
}
}
void debug(int x){ }
int query(int x, int y) {
makeroot(x);
access(y);
splay(y,);
return mx[y];
} vector<int> vec[MAXN];
int ans[MAXN]; class hdu5398 {
public:
void solve(std::istream &in, std::ostream &out) {
rep2(i, , MAXN-) {
vec[i].pb();
for (int j = ; j * j <= i; j++) {
if (i % j == ) {
vec[i].pb(j);
if (i / j != j)vec[i].pb(i / j);
}
}
sort(vec[i].begin(),vec[i].end());
}
Init(MAXN<<);
ans[] = ;
rep2(i, , MAXN-) {
int sz = vec[i].size();
int y = vec[i][sz - ];
ans[i] = ans[i - ];
link(i, MAXN + i);
rx[MAXN + i] = i;
link(y, MAXN + i);
lx[MAXN + i] = y;
key[MAXN + i] = y;
ans[i] += y;
dep(j, sz - , ) {
y = vec[i][j];
int x = query(y, i);
cut(x,lx[x]);
cut(x,rx[x]);
link(y, x);
link(i, x);
ans[i] -= key[x];
key[x] = y;
lx[x] = y;
rx[x] = i;
ans[i] += y;
}
}
int n;
while(in>>n){
out<<ans[n]<<endl;
} }
}; int main() {
std::ios::sync_with_stdio(false);
std::cin.tie();
hdu5398 solver;
std::istream &in(std::cin);
std::ostream &out(std::cout);
solver.solve(in, out);
return ;
}

hdu5398 GCD Tree(lct)的更多相关文章

  1. HDU 5002 Tree LCT 区间更新

    Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action?c ...

  2. BZOJ 3282: Tree( LCT )

    LCT.. -------------------------------------------------------------------------------- #include<c ...

  3. BZOJ 2631: tree( LCT )

    LCT...略麻烦... -------------------------------------------------------------------------------- #inclu ...

  4. [bzoj3282]Tree (lct)

    昨天看了一天的lct..当然幸好最后看懂了(也许吧..) 论善良学长的重要性T_T,老司机带带我! 这题主要是删边的时候还要判断一下..蒟蒻一开始天真的以为存在的边才能删结果吃了一发wa... 事实是 ...

  5. Link-Cut Tree(LCT)&TopTree讲解

    前言: Link-Cut Tree简称LCT是解决动态树问题的一种数据结构,可以说是我见过功能最强大的一种树上数据结构了.在此与大家分享一下LCT的学习笔记.提示:前置知识点需要树链剖分和splay. ...

  6. 动态树Link-cut tree(LCT)总结

    动态树是个好玩的东西 LCT题集 预备知识 Splay 树链剖分(好像关系并不大) 动态树(Link-cut tree) 先搬dalao博客 什么是LCT? 动态树是一类要求维护森林的连通性的题的总称 ...

  7. 洛谷P3690 [模板] Link Cut Tree [LCT]

    题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...

  8. 浅谈Link-Cut Tree(LCT)

    0XFF 前言&概念 Link-Cut Tree 是一种用来维护动态森林连通性的数据结构,适用于动态树问题.它采用类似树链剖分的轻重边路径剖分,把树边分为实边和虚边,并用 Splay 来维护每 ...

  9. Link-Cut Tree(LCT)

    转载自LCT(Link-Cut Tree)详解(蒟蒻自留地) 如果你还没有接触过LCT,你可以先看一看这里: (看不懂没关系,先留个大概的印像)http://www.cnblogs.com/BLADE ...

随机推荐

  1. 0X0000124

     求教卡饭网友,都快疯掉了.      最近搞设计,电脑频发出现蓝屏,今晚都出现三次了,新装的win7 64位系统,都是安装的原版光驱.     错误代码基本上都是:0x00000124 (0x000 ...

  2. 学c语言做练习

    /*编写一个函数,其功能是使输入字符串反序.在一个使用循环语句为这个函数提供输入的完整 程序中进行测试.*/ #include<stdio.h> #include<string.h& ...

  3. uva 10034 Problem A: Freckles

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  4. POJ 1987 Distance Statistics

    http://poj.org/problem?id=1987 题意:给一棵树,求树上有多少对节点满足距离<=K 思路:点分治,我们考虑把每个距离都存起来,然后排序,一遍扫描计算一下,注意还要减掉 ...

  5. 【HDOJ】1104 Remainder

    bfs. #include <cstdio> #include <cstring> #include <cstdlib> #include <queue> ...

  6. BZOJ3296: [USACO2011 Open] Learning Languages

    3296: [USACO2011 Open] Learning Languages Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 81  Solved: ...

  7. 【转】在Ubuntu 12.04 上为Virtualbox 启用USB 设备支持--不错

    原文网址:http://www.cnblogs.com/ericsun/archive/2013/06/10/3130679.html 虚拟机我一直在用,不是说离不开Windows,而是有些时候一些应 ...

  8. 使用java创建kafka的生产者和消费者

    创建一个Kafka的主题,连接到zk集群,副本因子3,分区3,主题名是test111        [root@h5 kafka]# bin/kafka-topics.sh --create --zo ...

  9. 【转】H264视频编码级别说明profile level Encoder

    版权声明:本文为博主原创文章,未经博主允许不得转载. 首先要阐明所谓的AVC其实就是H.264标准,是由ITU-T和ISO/IEC组成的联合视频组(JVT,Joint Video Team)一起开发的 ...

  10. css3 渐变linear-gradient

    background: -moz-linear-gradient(top, #FC641C, #FC761C); 参数:其共有三个参数,第一个参数表示线性渐变的方向,top 是从上到下.left 是从 ...