zoukankan      html  css  js  c++  java
  • [NOIP 2016] 天天爱跑步

    [题目链接]

               http://uoj.ac/problem/261

    [算法]

              树上差分 , 时间复杂度 : O(N + M)

    [代码]

           

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 1000010
    
    struct edge
    {
            int to,nxt;
    } e[MAXN << 1];
    
    int n,m,tot,timer;
    bool visited[MAXN];
    int f[MAXN],seq[MAXN],dfn[MAXN],fa[MAXN],dep[MAXN],w[MAXN],s[MAXN],t[MAXN],
            w1[MAXN],w2[MAXN],ans[MAXN],head[MAXN],size[MAXN],lca[MAXN],cnt1[MAXN],cnt2[MAXN];
    vector< pair<int,int> > q[MAXN],tag1[MAXN],tag2[MAXN],pos[MAXN];
    
    template <typename T> inline void read(T &x)
    {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; 
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline void addedge(int u,int v)
    {
            tot++;
            e[tot] = (edge){v,head[u]};
            head[u] = tot;
    }
    inline int get_root(int x)
    {
            if (f[x] == x) return x;
            return f[x] = get_root(f[x]);
    }
    inline void tarjan(int u,int father)
    {
            dfn[u] = ++timer;
            seq[timer] = u;
            size[u] = 1;
            visited[u] = true;
            for (int i = 0; i < (int)q[u].size(); i++)
            {
                    int v = q[u][i].first , id = q[u][i].second;
                    if (visited[v]) lca[id] = get_root(v); 
            }
            for (int i = head[u]; i; i = e[i].nxt)
            {
                    int v = e[i].to;
                    if (v == father) continue;
                    dep[v] = dep[u] + 1;
                    tarjan(v,u);
                    fa[v] = f[v] = u;
                    size[u] += size[v];
            }
    }
    int main() 
    {
            
            read(n); read(m);
            for (int i = 1; i < n; i++)
            {
                    int u,v;
                    read(u); read(v);
                    addedge(u,v);
                    addedge(v,u);
            }
            for (int i = 1; i <= n; i++) read(w[i]);
            for (int i = 1; i <= n; i++) f[i] = i;
            for (int i = 1; i <= m; i++)
            {
                    read(s[i]);
                    read(t[i]);    
                    q[s[i]].push_back(make_pair(t[i],i));
                    q[t[i]].push_back(make_pair(s[i],i));
            } 
            tarjan(1,-1);
            for (int i = 1; i <= n; i++) w1[i] = dep[i] + w[i];
            for (int i = 1; i <= n; i++) w2[i] = dep[i] - w[i];
            for (int i = 1; i <= m; i++)
            {
                    if (lca[i] == s[i]) 
                    {
                            tag2[t[i]].push_back(make_pair(dep[s[i]],1));
                            tag2[fa[s[i]]].push_back(make_pair(dep[s[i]],-1));
                    } else if (lca[i] == t[i])
                    {
                            tag1[s[i]].push_back(make_pair(dep[s[i]],1));
                            tag1[fa[t[i]]].push_back(make_pair(dep[s[i]],-1));
                    } else
                    {
                            tag1[s[i]].push_back(make_pair(dep[s[i]],1));
                            tag1[fa[lca[i]]].push_back(make_pair(dep[s[i]],-1));
                            tag2[t[i]].push_back(make_pair(2 * dep[lca[i]] - dep[s[i]],1));
                            tag2[lca[i]].push_back(make_pair(2 * dep[lca[i]] - dep[s[i]],-1));
                    }
            }
            for (int i = 1; i <= n; i++)
            {
                    pos[dfn[i] - 1].push_back(make_pair(i,-1));
                    pos[dfn[i] + size[i] - 1].push_back(make_pair(i,1));
            }
            int val = 2 * n;
            for (int i = 1; i <= n; i++)
            {
                    int u = seq[i];
                    for (int j = 0; j < (int)tag1[u].size(); j++)
                            cnt1[tag1[u][j].first + val] += tag1[u][j].second;
                    for (int j = 0; j < (int)tag2[u].size(); j++)
                            cnt2[tag2[u][j].first + val] += tag2[u][j].second; 
                    for (int j = 0; j < (int)pos[i].size(); j++)
                    {
                            ans[pos[i][j].first] += cnt1[w1[pos[i][j].first] + val] * pos[i][j].second;
                            ans[pos[i][j].first] += cnt2[w2[pos[i][j].first] + val] * pos[i][j].second; 
                    }
            }
            for (int i = 1; i < n; i++) printf("%d ",ans[i]);
            printf("%d
    ",ans[n]);
            
            return 0;
        
    }
  • 相关阅读:
    HDOJ 4747 Mex
    HDU 1203 I NEED A OFFER!
    HDU 2616 Kill the monster
    HDU 3496 Watch The Movie
    Codeforces 347A A. Difference Row
    Codeforces 347B B. Fixed Points
    Codeforces 372B B. Hungry Sequence
    HDU 1476 Sudoku Killer
    HDU 1987 How many ways
    HDU 2564 词组缩写
  • 原文地址:https://www.cnblogs.com/evenbao/p/9529620.html
Copyright © 2011-2022 走看看