zoukankan      html  css  js  c++  java
  • HDU

    HDU - 5398

    预处理维护出每个时刻的最大生成树, 就LCT维护就可以了。

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 3e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 998244353;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}
    
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    int n;
    LL ans[N];
    LL now;
    int tot;
    int U[N], V[N];
    vector<int> fac[N];
    
    struct LCT {
    #define l(x) (ch[x][0])
    #define r(x) (ch[x][1])
        int fa[N], ch[N][2], rev[N], sz[N], q[N];
        PII w[N], mn[N];
        void init(int n) {
            for(int i = 0; i <= n; i++) {
                fa[i] = rev[i] = 0;
                sz[i] = 1;
                mn[i] = w[i] = mk(1000000, i);
                ch[i][0] = ch[i][1] = 0;
            }
            tot = n + 1;
        }
        inline bool isroot(int x) {
            return l(fa[x]) != x && r(fa[x]) != x;
        }
        inline void pull(int x) {
            sz[x] = sz[l(x)] + sz[r(x)] + 1;
            mn[x] = w[x];
            chkmin(mn[x], mn[l(x)]);
            chkmin(mn[x], mn[r(x)]);
        }
        inline void push(int x) {
            if(rev[x]) {
                rev[x] = 0; swap(l(x), r(x));
                rev[l(x)] ^= 1; rev[r(x)] ^= 1;
            }
        }
        inline void rot(int x) {
            int y = fa[x], z = fa[y], l, r;
            if(ch[y][0] == x) l = 0, r = l ^ 1;
            else l = 1, r = l ^ 1;
            if(!isroot(y)) {
                if(l(z) == y) l(z) = x;
                else r(z) = x;
            }
            fa[x] = z; fa[y] = x; fa[ch[x][r]]=y;
            ch[y][l] = ch[x][r]; ch[x][r] = y;
            pull(y); pull(x);
        }
        inline void splay(int x) {
            int top = 1; q[top] = x;
            for(int i = x; !isroot(i); i = fa[i]) q[++top] = fa[i];
            for(int i = top; i; i--) push(q[i]);
            while(!isroot(x)) {
                int y = fa[x], z = fa[y];
                if(!isroot(y)) {
                    if((l(y) == x) ^ (l(z) == y)) rot(x);
                    else rot(y);
                }
                rot(x);
            }
        }
        inline void access(int x) {
            for(int y = 0; x; y = x, x = fa[x]) {
                splay(x);
                r(x) = y;
                pull(x);
            }
        }
        inline void makeroot(int x) {
            access(x); splay(x); rev[x] ^= 1;
        }
        inline int findroot(int x) {
            access(x); splay(x);
            while(l(x)) x = l(x);
            return x;
        }
        inline void split(int x, int y) {
            makeroot(x); access(y); splay(y);
        }
        inline void link(int x, int y) {
            makeroot(x); fa[x] = y; splay(x);
        }
        inline void cut(int x, int y) {
            split(x, y);
            if(l(y) == x) l(y) = 0, fa[x] = 0;
        }
        void change(int x, int y, int weight) {
            if(findroot(x) != findroot(y)) {
                ++tot;
                w[tot] = mk(weight, tot);
                U[tot] = x; V[tot] = y;
                sz[tot] = 1;
                link(x, tot);
                link(y, tot);
                now += weight;
                return;
            }
    
            makeroot(x);
            access(y);
            splay(y);
            PII minVal = mn[y];
    
            if(minVal.fi >= weight) return;
            cut(minVal.se, V[minVal.se]);
            cut(minVal.se, U[minVal.se]);
            now -= minVal.fi;
    
            w[minVal.se] = mk(weight, minVal.se);
            U[minVal.se] = x; V[minVal.se] = y;
            sz[minVal.se] = 1;
            link(x, minVal.se);
            link(y, minVal.se);
            now += weight;
        }
    } lct;
    
    int main() {
        for(int i = 1; i <= 100000; i++) {
            for(int j = i + i; j <= 100000; j += i) {
                fac[j].push_back(i);
            }
        }
    
        lct.init(100000);
    
        for(int i = 2; i <= 100000; i++) {
            for(int j : fac[i]) {
                lct.change(i, j, j);
            }
            ans[i] = now;
        }
    
        while(scanf("%d", &n) != EOF) {
            printf("%lld
    ", ans[n]);
        }
        return 0;
    }
  • 相关阅读:
    Python进程、线程
    Maven项目的坐标GroupId和ArtifactId
    java中的变量
    java中new一个对象的执行过程及类的加载顺序
    java中string和int互相转化
    什么是设计模式?
    Mybatis解决了JDBC编程哪些问题
    SQL注入、占位符拼接符
    JDBC、事务和连接池
    关于Spring配置文件xml文档的schema约束
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11274169.html
Copyright © 2011-2022 走看看