• bzoj 1103


    题目大意:有一棵树根为1,刚开始每条边的权值为1,  现在有m + n - 1 个操作, A :x  y  , 将x和y相连的边权值变为1, W:x, 询问x到1路径上的权值和。

    思路 : 方法一: 用dfs序建立树状数组, 每个点入栈位置的值为1, 出栈为-1, 询问的值就是sum( l [ x ] ), 修改就将出栈,入栈的点全部变成1, 巧妙的地方在于

    利用dfs序求前缀和会把不是在这条链上的边全部抵消掉。

    方法二:用dfs序建立线段数, 线段数里每个点表示该点到1的权值和, 修改一条边相当于把该边下边的子树的值全部减1, 相当于区间修改。

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define fi first
     4 #define se second
     5 #define mk make_pair
     6 #define pii pair<int,int>
     7 
     8 using namespace std;
     9 
    10 const int N=5e5+7;
    11 const int M=1e4+7;
    12 const int inf=0x3f3f3f3f;
    13 const LL INF=0x3f3f3f3f3f3f3f3f;
    14 const int mod=1e9 + 7;
    15 
    16 int n, m, tot, st[N], l[N], r[N];
    17 
    18 struct BIT {
    19     int a[N];
    20     void modify(int pos, int v) {
    21         for(int i = pos; i <= tot; i += i & -i)
    22             a[i] += v;
    23     }
    24 
    25     int sum(int pos) {
    26         int ans = 0;
    27         for(int i = pos; i; i -= i & -i)
    28             ans += a[i];
    29         return ans;
    30     }
    31 }bit;
    32 
    33 vector<int> edge[N];
    34 void dfs(int u) {
    35     l[u] = ++tot;
    36     for(int i = 0; i < edge[u].size(); i++) {
    37         int v = edge[u][i];
    38         dfs(v);
    39     }
    40     r[u] = ++tot;
    41 }
    42 int main() {
    43     scanf("%d", &n);
    44     for(int i = 1; i < n; i++) {
    45         int u, v; scanf("%d%d", &u, &v);
    46         if(u > v) swap(u, v);
    47         edge[u].push_back(v);
    48     }
    49     dfs(1);
    50     for(int i = 1; i <= n; i++) {
    51         bit.modify(l[i], 1);
    52         bit.modify(r[i], -1);
    53     }
    54     scanf("%d", &m);
    55     m += n - 1;
    56     while(m--) {
    57         char s[5]; scanf("%s", s);
    58         if(s[0] == 'A') {
    59             int u, v; scanf("%d%d", &u, &v);
    60             if(u > v) swap(u, v);
    61             bit.modify(l[v], -1);
    62             bit.modify(r[v], 1);
    63         } else {
    64             int x; scanf("%d", &x);
    65             printf("%d
    ", bit.sum(l[x]) - 1);
    66         }
    67     }
    68     return 0;
    69 }
    70 /*
    71 */
  • 相关阅读:
    ARC071F Infinite Sequence
    AGC043C Giant Graph
    ARC006E Addition and Subtraction Hard
    Codechef BALNET Balancing Network Revisited
    Gym102055H Game on the Tree
    Luogu P5320 [BJOI2019]勘破神机
    cookie和session
    jsp介绍
    request请求转换成对象。
    域对象 request
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9005054.html
Copyright © 2020-2023  润新知