# 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

Input

Output
For each test case, print the answer.

Sample Input
1
2
3
4
5

Sample Output
0
1
2
4
5

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

  1 /**
2  * code generated by JHelper
4  * @author xyiyy @https://github.com/xyiyy
5  */
6
7 #include <iostream>
8 #include <fstream>
9
10 //#####################
11 //Author:fraud
12 //Blog: http://www.cnblogs.com/fraud/
13 //#####################
15 #include <iostream>
16 #include <sstream>
17 #include <ios>
18 #include <iomanip>
19 #include <functional>
20 #include <algorithm>
21 #include <vector>
22 #include <string>
23 #include <list>
24 #include <queue>
25 #include <deque>
26 #include <stack>
27 #include <set>
28 #include <map>
29 #include <cstdio>
30 #include <cstdlib>
31 #include <cmath>
32 #include <cstring>
33 #include <climits>
34 #include <cctype>
35
36 using namespace std;
37 #define XINF INT_MAX
38 #define INF 0x3FFFFFFF
39 #define mp(X, Y) make_pair(X,Y)
40 #define pb(X) push_back(X)
41 #define rep(X, N) for(int X=0;X<N;X++)
42 #define rep2(X, L, R) for(int X=L;X<=R;X++)
43 #define dep(X, R, L) for(int X=R;X>=L;X--)
44 #define clr(A, X) memset(A,X,sizeof(A))
45 #define IT iterator
46 #define ALL(X) (X).begin(),(X).end()
47 #define PQ std::priority_queue
48 typedef long long ll;
49 typedef unsigned long long ull;
50 typedef pair<int, int> PII;
51 typedef vector<PII> VII;
52 typedef vector<int> VI;
53
54 const int MAXN = 100010;
55 int pre[MAXN<<1], ch[MAXN<<1][2], rev[MAXN<<1];
56 int key[MAXN<<1];
57 int lx[MAXN<<1],rx[MAXN<<1];
58 int mx[MAXN<<1];
59
60 void push_down(int r) {
61     if(!r)return;
62     if (rev[r]) {
63         rev[ch[r][0]] ^= 1;
64         rev[ch[r][1]] ^= 1;
65         swap(ch[r][0], ch[r][1]);
66         rev[r] ^= 1;
67     }
68 }
69
70 void push_up(int x) {
71     int l = ch[x][0],r = ch[x][1];
72     mx[x] = x;
73     if(key[mx[l]]<key[mx[x]])mx[x] = mx[l];
74     if(key[mx[r]]<key[mx[x]])mx[x] = mx[r];
75 }
76
77 void rotate(int x, int d) {
78     const int y = pre[x];
79     ch[y][!d] = ch[x][d];
80     if (ch[x][d])pre[ch[x][d]] = y;
81     pre[x] = pre[y];
82     if (ch[pre[y]][0] == y)ch[pre[x]][0] = x;
83     else if (ch[pre[y]][1] == y)ch[pre[x]][1] = x;
84     pre[y] = x;
85     ch[x][d] = y;
86     push_up(y);
87 }
88
89 bool _splay_parent(int x,int &y){
90     return (y = pre[x])!=0 && (ch[y][0] == x || ch[y][1] == x);
91 }
92
93 void splay(int x,int goal) {
94     push_down(x);
95     for (int y,z;_splay_parent(x,y);) {
96             //cout<<x<<" "<<y<<endl;
97         if(_splay_parent(y,z)){
98             push_down(z);push_down(y);push_down(x);
99             int d = y == ch[z][0];
100             if(x == ch[y][d])rotate(x,d^1),rotate(x,d);
101             else rotate(y,d),rotate(x,d);
102         }else {
103             push_down(y),push_down(x);
104             rotate(x, x == ch[y][0]);break;
105         }
106     }
107     push_up(x);
108 }
109
110 int access(int u) {
111     int v = 0;
112     for (; u; u = pre[u]) {
113         splay(u,0);
114         ch[u][1] = v;
115         push_up(v = u);
116     }
117     return v;
118 }
119
120 void makeroot(int x) {
121     rev[access(x)] ^= 1;
122     splay(x,0);
123 }
124
125 void link(int x, int y) {
126     makeroot(x);
127     pre[x] = y;
128 }
129
130 void cut(int x, int y) {
131     makeroot(x);
132     access(y);
133     splay(y,0);
134     pre[ch[y][0]] = 0;
135     ch[y][0] = 0;
136     push_up(y);
137 }
138
139 void Init(int n) {
140     for (int i = 0; i < n; i++) {
141         pre[i] = ch[i][0] = ch[i][1] = 0;
142         key[i] = INF;
143         mx[i] = 0;
144     }
145 }
146 void debug(int x){
147
148 }
149 int query(int x, int y) {
150     makeroot(x);
151     access(y);
152     splay(y,0);
153     return mx[y];
154 }
155
156
157 vector<int> vec[MAXN];
158 int ans[MAXN];
159
160 class hdu5398 {
161 public:
162     void solve(std::istream &in, std::ostream &out) {
163         rep2(i, 2,  MAXN-1) {
164             vec[i].pb(1);
165             for (int j = 2; j * j <= i; j++) {
166                 if (i % j == 0) {
167                     vec[i].pb(j);
168                     if (i / j != j)vec[i].pb(i / j);
169                 }
170             }
171             sort(vec[i].begin(),vec[i].end());
172         }
173         Init(MAXN<<1);
174         ans[1] = 0;
175         rep2(i, 2, MAXN-5) {
176             int sz = vec[i].size();
177             int y = vec[i][sz - 1];
178             ans[i] = ans[i - 1];
180             rx[MAXN + i] = i;
182             lx[MAXN + i] = y;
183             key[MAXN + i] = y;
184             ans[i] += y;
185             dep(j, sz - 2, 0) {
186                 y = vec[i][j];
187                 int x = query(y, i);
188                 cut(x,lx[x]);
189                 cut(x,rx[x]);
192                 ans[i] -= key[x];
193                 key[x] = y;
194                 lx[x] = y;
195                 rx[x] = i;
196                 ans[i] += y;
197             }
198         }
199         int n;
200         while(in>>n){
201             out<<ans[n]<<endl;
202         }
203
204     }
205 };
206
207 int main() {
208     std::ios::sync_with_stdio(false);
209     std::cin.tie(0);
210     hdu5398 solver;
211     std::istream &in(std::cin);
212     std::ostream &out(std::cout);
213     solver.solve(in, out);
214     return 0;
215 }

posted on 2015-08-18 23:52  xyiyy  阅读(...)  评论(...编辑  收藏

• 随笔 - 102
• 文章 - 0
• 评论 - 7
• 引用 - 0