hdu5398 GCD Tree(lct)

转载请注明出处: 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(1n105).
 


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

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

  1 /**
  2  * code generated by JHelper
  3  * More info: https://github.com/AlexeyDmitriev/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 //#####################
 14 //#pragma comment(linker, "/STACK:102400000,102400000")
 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];
179             link(i, MAXN + i);
180             rx[MAXN + i] = i;
181             link(y, MAXN + 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]);
190                 link(y, x);
191                 link(i, 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  阅读(410)  评论(0编辑  收藏  举报

导航