标签:
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 84 Accepted Submission(s): 38
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 }
标签:
原文地址:http://www.cnblogs.com/fraud/p/4741066.html