zoukankan      html  css  js  c++  java
  • codeforces 463E . Caisa and Tree

    题目链接

    给一棵树, 两种操作, 一种是将点u的权值改为y, 另一种是查询根节点到点u的路径上, gcd(v, u)>1的深度最深的点v。 修改操作不超过50次。

    这个题, 暴力可以过, 但是在cf上找到了一个神奇的代码。 

    如果没有修改, 那么就将询问存起来。 如果有了修改, 就dfs一次, 将之前的询问都处理完, 然后在修改。 跑的很快....

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <string>
    #include <queue>
    #include <stack>
    #include <bitset>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define lson l, m, rt<<1
    #define mem(a) memset(a, 0, sizeof(a))
    #define rson m+1, r, rt<<1|1
    #define mem1(a) memset(a, -1, sizeof(a))
    #define mem2(a) memset(a, 0x3f, sizeof(a))
    #define rep(i, n, a) for(int i = a; i<n; i++)
    #define fi first
    #define se second
    typedef pair<int, int> pll;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 1e9+7;
    const int inf = 1061109567;
    const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    const int maxn = 1e5+5;
    int val[maxn], head[maxn*2], num, ans[maxn];
    struct node
    {
        int to, nextt;
    }e[maxn*2];
    void add(int u, int v) {
        e[num].to = v;
        e[num].nextt = head[u];
        head[u] = num++;
    }
    vector <int> Q[maxn], st;
    void dfs(int u, int fa) {
        if(!Q[u].empty()) {
            int k = st.size()-1;
            while(k>=0&&__gcd(val[st[k]], val[u])==1)
                k--;
            if(~k)
                k = st[k];
            for(auto i: Q[u])
                ans[i] = k;
            Q[u].clear();
        }
        st.pb(u);
        for(int i = head[u]; ~i; i = e[i].nextt) {
            int v = e[i].to;
            if(v == fa)
                continue;
            dfs(v, u);
        }
        st.pop_back();
    }
    int main()
    {
        int n, m, x, y, sign;
        scanf("%d%d", &n, &m);
        mem1(head);
        for(int i = 1; i<=n; i++)
            scanf("%d", &val[i]);
        for(int i = 0; i<n-1; i++) {
            scanf("%d%d", &x, &y);
            add(x, y);
            add(y, x);
        }
        int cnt = 0;
        for(int i = 0; i<m; i++) {
            scanf("%d", &sign);
            if(sign == 1) {
                scanf("%d", &y);
                Q[y].pb(i);
                cnt++;
            } else {
                scanf("%d%d", &x, &y);
                if(cnt)
                    dfs(1, 0);
                val[x] = y;
                cnt = 0;
                ans[i] = -2;
            }
        }
        if(cnt)
            dfs(1, 0);
        for(int i = 0; i<m; i++) {
            if(ans[i] != -2)
                printf("%d
    ", ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    【极角排序、扫描线】UVa 1606
    【计算几何】是时候知道这些函数了
    【技巧性(+递归运用)】UVa 1596
    【策略】UVa 11389
    【策略】UVa 1344
    夏季吃西瓜,会勤上厕所,会导致体内缺水,导致便秘,,会长豆豆
    Alt+Shift+R组合键,用来在一个java文件中批量的重命名变量。
    Pycharm-professional-2017.2.3破解安装
    通过反编译深入理解Java String及intern
    转:MyEclipse安装Eclipse Memory Analyzer插件,并进行错误文件分析流程
  • 原文地址:https://www.cnblogs.com/yohaha/p/5099443.html
Copyright © 2011-2022 走看看