zoukankan      html  css  js  c++  java
  • [虚树][树状数组]JZOJ 5908 开荒

    Description

    题目背景:
    尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门。他加入师门后发现有无穷无尽的师兄弟姐妹,这几天新副本开了,尊者神高达的师门作为一个 pve师门,于是他们决定组织一起去开荒。

    题目描述:
    师门可以看做以 1 为根的一棵树,师门中的每一个人都有一定的装备分数。一共会有 q 个事件。每个事件可能是一次开荒,也可能是因为开荒出了好装备而导致一个人的装分出现了变化。对于一次开荒,会有 k 个人组织,由于师门的号召力很强,所以所有在组织者中任意两个人简单路径上的人都会参加。
     

    Input

    第一行 n ,q;
    接下来 1 行 n 个数,代表每个人的分值;
    接下来 n-1 行 u,v 代表一条边
    接下来 q 行
    Q 代表询问,接下来 k 个数代表组织的人数,读入为 0时停止读入。
    C 代表修改,输入 x,w 代表将 x 的分值变为 w

    Output

    共 Q 的数量行,为开荒的人的总分值
     

    Sample Input

    4 4
    10 5 2 2
    1 2
    2 3
    2 4
    Q 3 4 0
    C 3 200
    Q 3 4 0
    Q 1 4 0

    Sample Output

    9
    207
    17
    
    样例解释:
    第一次询问,参加的人有 2,3,4 5+2+2=9
    第一次修改,权值为 10 5 200 2
    第二次询问,参加的人有 2,3,4 5+200+2=207
    第三次询问,参加的人有 1,2,4 10+5+2=17
     

    Data Constraint

    数据范围:
    20%的数据 n<=10000,q<=500;
    另外 20%的数据 k=2
    另外 20%的数据 没有修改操作
    所有数据 n,q<=100000,所有询问 k 的和<=1000000
    保证数据合法

    分析

    由于询问点少,我们考虑建虚树(假

    然后用树状数组维护关键节点的和就行了

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <stack>
    #define lowbit(x) x&-x
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    struct Edge {
        int u,v,nx;
    }g[2*N];
    int cnt,list[N];
    ll c[N],w[N];
    int st[N],ed[N],tme;
    int dep[N],f[N][21];
    int a[2*N],acnt;
    int n,q;
    
    void Addedge(int u,int v) {
        g[++cnt].u=u;g[cnt].v=v;g[cnt].nx=list[u];list[u]=cnt;
    }
    
    int LCA(int u,int v) {
        if (dep[u]<dep[v]) swap(u,v);
        for (int i=20;i>=0;i--)
            if (dep[f[u][i]]>=dep[v]) u=f[u][i];
        if (u==v) return u;
        for (int i=20;i>=0;i--)
            if (f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
        return f[u][0];
    }
    
    void Dfs(int u,int fa) {
        st[u]=++tme;dep[u]=dep[fa]+1;
        for (int i=1;i<=20;i++) f[u][i]=f[f[u][i-1]][i-1];
        for (int i=list[u];i;i=g[i].nx)
            if (g[i].v!=fa) {
                f[g[i].v][0]=u;
                Dfs(g[i].v,u);
            }
        ed[u]=tme;
    }
    
    void Add(int x,ll y) {
        for (int i=x;i<=n;i+=lowbit(i)) c[i]+=y;
    }
    
    ll Get_Sum(int x) {
        ll ans=0;
        for (int i=x;i;i-=lowbit(i)) ans+=c[i];
        return ans;
    }
    
    bool Cmp(int a,int b) {
        return st[a]<st[b];
    }
    
    int main() {
        freopen("kaihuang.in","r",stdin);
        freopen("kaihuang.out","w",stdout);
        scanf("%d%d",&n,&q);
        for (int i=1;i<=n;i++) scanf("%lld",&w[i]);
        for (int i=1;i<n;i++) {
            int u,v;
            scanf("%d%d",&u,&v);
            Addedge(u,v);Addedge(v,u);
        }
        Dfs(1,0);
        for (int i=1;i<=n;i++) Add(st[i],w[i]),Add(ed[i]+1,-w[i]);
        for (int i=1;i<=q;i++) {
            char c;
            do {
                scanf("%c",&c);
            }
            while (c!='C'&&c!='Q');
            if (c=='C') {
                int a;ll b;
                scanf("%d%lld",&a,&b);
                Add(st[a],b-w[a]);Add(ed[a]+1,w[a]-b);
                w[a]=b;
                continue;
            }
            acnt=0;
            do {
                acnt++;
                scanf("%d",&a[acnt]);
            }
            while (a[acnt]!=0);
            acnt--;
            sort(a+1,a+acnt+1,Cmp);
            int fakeacnt=acnt;
            for (int i=1;i<fakeacnt;i++)
                a[++acnt]=LCA(a[i],a[i+1]);
            sort(a+1,a+acnt+1,Cmp);acnt=unique(a+1,a+acnt+1)-a-1;
            stack<int> stk;
            ll ans=0;
            while (!stk.empty()) stk.pop();
            for (int i=1;i<=acnt;i++) {
                for (;!stk.empty()&&ed[stk.top()]<st[a[i]];stk.pop());
                ans+=!stk.empty()?Get_Sum(st[a[i]])-Get_Sum(st[stk.top()]):w[a[i]];
                stk.push(a[i]);
            }
            printf("%lld
    ",ans);
        }
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    判断当前时间为星期几
    springboot+mysql数据源切换
    表单上传图片
    po,vo,bo,dto,dao解释
    生成电脑的SSH key
    单例模式
    事物的特性和隔离级别
    springAOP自定义注解讲解
    Spring依赖注入(DI)的三种方式
    redis持久化
  • 原文地址:https://www.cnblogs.com/mastervan/p/9813703.html
Copyright © 2011-2022 走看看