• 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 }
  • 相关阅读:
    bzoj 4034 [HAOI2015]树上操作——树链剖分
    bzoj 1179 [Apio2009]Atm——SCC缩点+spfa
    bzoj 1123 [POI2008]BLO——点双连通分量
    poj1830开关问题——异或高斯消元
    bzoj2004公交线路——DP+矩阵加速递推
    bzoj2875随机数生成器——矩阵快速幂
    Splay模板
    map插入与查找
    bzoj1013高斯消元
    bzoj2257瓶子与燃料——最大公约数
  • 原文地址:https://www.cnblogs.com/fraud/p/4741066.html
Copyright © 2020-2023  润新知