zoukankan      html  css  js  c++  java
  • HDU

    HDU - 5799

    第一部分可以dfs序莫队, 或者可以dsu on tree。

    第二部分需要树上莫队, 我写的是欧拉序的好像比树分块的常数要大。。

    用快读卡过去了。

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #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)                     ;
    
    #define ll long long
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = (int)1e9 + 7;
    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());
    
    struct FastIO {
        static const int S = 1e7;
        int wpos;
        char wbuf[S];
        FastIO() : wpos(0) {}
        inline int xchar() {
            static char buf[S];
            static int len = 0, pos = 0;
            if (pos == len)
                pos = 0, len = fread(buf, 1, S, stdin);
            if (pos == len) exit(0);
            return buf[pos++];
        }
        inline int xuint() {
            int c = xchar(), x = 0;
            while (c <= 32) c = xchar();
            for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
            return x;
        }
        inline int xint()
        {
            int s = 1, c = xchar(), x = 0;
            while (c <= 32) c = xchar();
            if (c == '-') s = -1, c = xchar();
            for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
            return x * s;
        }
        inline void xstring(char *s)
        {
            int c = xchar();
            while (c <= 32) c = xchar();
            for (; c > 32; c = xchar()) * s++ = c;
            *s = 0;
        }
        inline void wchar(int x)
        {
            if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
            wbuf[wpos++] = x;
        }
        inline void wint(ll x)
        {
            if (x < 0) wchar('-'), x = -x;
            char s[24];
            int n = 0;
            while (x || !n) s[n++] = '0' + x % 10, x /= 10;
            while (n--) wchar(s[n]);
        }
        inline void wstring(const char *s)
        {
            while (*s) wchar(*s++);
        }
        ~FastIO()
        {
            if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
        }
    } io;
    
    const int LOG = 17;
    int n, m, B, a[N];
    vector<int> G[N];
    int qus[N][5];
    LL ans[N];
    
    int in[N], ot[N], id[N], depth[N], idx;
    int pa[N][LOG];
    
    int qcnt;
    struct Qus {
        int L, R, a, b, id, lca;
        bool operator < (const Qus &rhs) const {
            if(L / B != rhs.L / B) return L < rhs.L;
            else return R < rhs.R;
        }
    } q[N];
    
    int hs[N], hscnt;
    
    void dfs(int u, int fa) {
        pa[u][0] = fa;
        depth[u] = depth[fa] + 1;
        for(int i = 1; i < LOG; i++) {
            pa[u][i] = pa[pa[u][i - 1]][i - 1];
        }
        for(auto &v : G[u]) {
            if(v == fa) continue;
            dfs(v, u);
        }
    }
    
    int getLca(int u, int v) {
        if(depth[u] < depth[v]) swap(u, v);
        int d = depth[u] - depth[v];
        for(int i = LOG - 1; ~i; i--) {
            if(d >> i & 1) {
                u = pa[u][i];
            }
        }
        if(u == v) return u;
        for(int i = LOG - 1; ~i; i--) {
            if(pa[u][i] != pa[v][i]) {
                u = pa[u][i];
                v = pa[v][i];
            }
        }
        return pa[u][0];
    }
    
    void dfs1(int u, int fa) {
        in[u] = ++idx;
        id[idx] = u;
        for(auto &v : G[u]) {
            if(v == fa) continue;
            dfs1(v, u);
        }
        ot[u] = idx;
    }
    
    void dfs2(int u, int fa) {
        in[u] = ++idx;
        id[idx] = u;
        for(auto &v : G[u]) {
            if(v == fa) continue;
            dfs2(v, u);
        }
        ot[u] = ++idx;
        id[idx] = u;
    }
    
    int c1[N], op[N];
    LL c2[N];
    
    inline void update1(int x, int op) {
        x = a[id[x]];
        c2[c1[x]] -= hs[x];
        c1[x] += op;
        c2[c1[x]] += hs[x];
    }
    
    
    void solve1() {
        qcnt = idx = 0;
        dfs1(1, 0);
        for(int i = 1; i <= m; i++) {
            if(qus[i][0] == 2) continue;
            q[++qcnt] = Qus{in[qus[i][1]], ot[qus[i][1]], qus[i][3], qus[i][4], i, 0};
        }
        B = sqrt(n) + 1;
        sort(q + 1, q + 1 + qcnt);
        for(int i = 0; i <= hscnt; i++) {
            c1[i] = 0;
        }
        for(int i = 0; i <= n; i++) {
            c2[i] = 0;
        }
        int l = 1, r = 0, L, R, a, b, id;
        for(int o = 1; o <= qcnt; o++) {
            L = q[o].L; R = q[o].R;
            a = q[o].a; b = q[o].b; id = q[o].id;
            while(r < R) update1(++r, 1);
            while(l > L) update1(--l, 1);
            while(r > R) update1(r--, -1);
            while(l < L) update1(l++, -1);
            ans[id] = __gcd(c2[a], c2[b]);
        }
    }
    
    inline void update2(int x) {
        x = id[x];
        c2[c1[a[x]]] -= hs[a[x]];
        c1[a[x]] += op[x];
        c2[c1[a[x]]] += hs[a[x]];
        op[x] = -op[x];
    }
    
    void solve2() {
        qcnt = idx = 0;
        dfs2(1, 0);
        for(int i = 1; i <= m; i++) {
            if(qus[i][0] == 1) continue;
            int a = qus[i][1], b = qus[i][2];
            int lca = getLca(a, b);
            if(lca == a) {
                q[++qcnt] = Qus{in[a], in[b], qus[i][3], qus[i][4], i, lca};
            }
            else if(lca == b) {
                q[++qcnt] = Qus{in[b], in[a], qus[i][3], qus[i][4], i, lca};
            }
            else {
                if(in[a] <= in[b]) q[++qcnt] = Qus{ot[a], in[b], qus[i][3], qus[i][4], i, lca};
                else q[++qcnt] = Qus{ot[b], in[a], qus[i][3], qus[i][4], i, lca};
            }
        }
    
        B = 4 * sqrt(n) + 1;
        sort(q + 1, q + 1 + qcnt);
    
        for(int i = 0; i <= hscnt; i++) {
            c1[i] = 0;
        }
        for(int i = 0; i <= n; i++) {
            op[i] = 1;
            c2[i] = 0;
        }
    
        int l = 1, r = 0, L, R, a, b, qid, lca;
    
        for(int o = 1; o <= qcnt; o++) {
            L = q[o].L; R = q[o].R;
            a = q[o].a; b = q[o].b;
            qid = q[o].id; lca = q[o].lca;
            while(r < R) update2(++r);
            while(l > L) update2(--l);
            while(r > R) update2(r--);
            while(l < L) update2(l++);
            if(lca != id[L] && lca != id[R]) {
                c2[c1[::a[lca]]] -= hs[::a[lca]];
                c1[::a[lca]]++;
                c2[c1[::a[lca]]] += hs[::a[lca]];
                ans[qid] = __gcd(c2[a], c2[b]);
                c2[c1[::a[lca]]] -= hs[::a[lca]];
                c1[::a[lca]]--;
                c2[c1[::a[lca]]] += hs[::a[lca]];
            }
            else {
                ans[qid] = __gcd(c2[a], c2[b]);
            }
        }
    }
    
    
    void init() {
        hscnt = idx = 0;
        for(int i = 1; i <= n; i++) {
            G[i].clear();
        }
    }
    
    char s[] = "Case #";
    
    int main() {
    //    freopen("test.txt", "r", stdin);
    //    freopen("1.out", "w", stdout);
        int T, cas = 0;
    //    scanf("%d", &T);
        T = io.xint();
        while(T--) {
    //        scanf("%d%d", &n, &m);
            n = io.xint(); m = io.xint();
            init();
            for(int i = 1; i <= n; i++) {
    //            scanf("%d", &a[i]);
                a[i] = io.xint();
                hs[++hscnt] = a[i];
            }
            for(int i = 1; i < n; i++) {
                int u, v;
    //            scanf("%d%d", &u, &v);
                u = io.xint(); v = io.xint();
                G[u].push_back(v);
                G[v].push_back(u);
            }
            for(int i = 1; i <= m; i++) {
                for(int j = 0; j < 5; j++) {
    //                scanf("%d", &qus[i][j]);
                    qus[i][j] = io.xint();
                }
            }
            sort(hs + 1, hs + 1 + hscnt);
            hscnt = unique(hs + 1, hs + 1 + hscnt) - hs - 1;
            for(int i = 1; i <= n; i++) {
                a[i] = lower_bound(hs + 1, hs + 1 + hscnt, a[i]) - hs;
            }
            dfs(1, 0);
            solve1();
            solve2();
    //        printf("Case #%d:
    ", ++cas);
            io.wstring(s);
            io.wint(++cas);
            io.wchar(':');
            io.wchar('
    ');
            for(int i = 1; i <= m; i++) {
    //            printf("%lld
    ", ans[i]);
                io.wint(ans[i]);
                io.wchar('
    ');
            }
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    XML与JSON的区别?各自有哪些优缺点?
    js数组操作(增、删、改、查)
    Ajax缓存原理
    Ajax的跨域问题分析
    简单理解javascript的闭包
    CSS的导入方式:link与import方式的区别
    谈谈iframe的优缺点
    winform全局异常捕获
    Dispatcher.BeginInvoke()方法使用不当导致UI界面卡死的原因分析
    解决asp.net中“从客户端中检测到有潜在危险的Request.Form值”的错误
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11474622.html
Copyright © 2011-2022 走看看