zoukankan      html  css  js  c++  java
  • Wannafly Camp 2020 Day 2F 采蘑菇的克拉莉丝

    如果暴力维护,每次询问时需要对所有孩子做计算

    考虑通过树剖来平衡修改与询问的时间,询问时计算重链和父树,轻链的贡献预先维护好,修改时则需要修改可能影响的轻链贡献,因为某个点到根的路径上轻重交替只有 (O(log n)) 个,所以只需要修改这么多次,于是复杂度有保证,树状数组维护子树即可

    我真是个憨憨,打错树剖调一晚,地上蛙血一大摊

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N = 1e6+5;
    
    int ar[N]; // index: 1 ~ N
    int lowbit(int t) { return t & (-t); }
    void add(int i, int v) {
    	for (; i < N; ar[i] += v, i += lowbit(i));
    }
    void add(int i, int j, int v) {
        add (j+1, -v);
        add (i, v);
    }
    int sum(int i) {
    	int s = 0;
    	for (; i > 0; s += ar[i], i -= lowbit(i));
    	return s;
    }
    
    vector <pair<int,int> > g[N];
    int n,m,t1,t2,t3,pos;
    int fa[N],siz[N],f[N],cnt[N],wson[N],len[N],dfn[N],top[N],ind,tot;
    
    void dfs1(int p) {
        siz[p]=1;
        for(pair<int,int> pr:g[p]) {
            int q=pr.first, w=pr.second;
            if(q==fa[p]) continue;
            fa[q]=p;
            len[q]=w;
            dfs1(q);
            siz[p]+=siz[q];
            if(siz[q]>siz[wson[p]]) wson[p]=q;
        }
    }
    
    void dfs2(int p) {
        dfn[p]=++ind;
        if(wson[p]) {
            top[wson[p]]=top[p];
            dfs2(wson[p]);
        }
        for(pair<int,int> pr:g[p]) {
            int q=pr.first, w=pr.second;
            if(q==fa[p]) continue;
            if(q==wson[p]) continue;
            top[q]=q;
            dfs2(q);
        }
    }
    
    void modify(int v,int x) {
        cnt[v]+=x;
        //v=fa[v];
        while(v) {
            int t=top[v];
            add(dfn[t],dfn[v],x);
            f[fa[t]]+=x*len[t];
            v=fa[t];
        }
        f[0]=0;
    }
    
    int query(int p) {
        int ans=0;
        ans+=sum(dfn[wson[p]])*len[wson[p]];
        ans+=f[p];
        ans+=len[p]*(tot-sum(dfn[p]));
        //cout<<sum(dfn[wson[p]])<<"*"<<len[wson[p]]<<" + "<<
        //f[p]<<" + "<<len[p]<<"*"<<(tot-sum(dfn[p]))<<" = "<<ans<<endl;
        return ans;
    }
    
    signed main() {
        scanf("%lld",&n);
        for(int i=1;i<n;i++) {
            scanf("%lld%lld%lld",&t1,&t2,&t3);
            g[t1].push_back(make_pair(t2,t3));
            g[t2].push_back(make_pair(t1,t3));
        }
        dfs1(1);
        top[1]=1;
        dfs2(1);
        pos=1;
        scanf("%lld",&m);
        for(int i=1;i<=m;i++) {
            scanf("%lld%lld",&t1,&t2);
            if(t1==1) scanf("%lld",&t3), tot+=t3;
            if(t1==1) modify(t2,t3);
            else pos=t2;
            printf("%lld
    ",query(pos));
        }
    }
    
  • 相关阅读:
    jxl导出excel的问题
    java.lang.IllegalStateException: getOutputStream() has already been called for this response解决方案
    在MyEclipse中用debug调试应用程序
    添加 MyEclipse Persistence Tools 类库
    使用递归算法结合数据库解析成java树形结构
    String.format()用法
    在ubuntu下使用Eclipse搭建Hadoop开发环境
    Ubuntu下伪分布式模式Hadoop的安装及配置
    ubuntu10.10手工安装jdk1.6
    docker 清理容器和镜像
  • 原文地址:https://www.cnblogs.com/mollnn/p/12327951.html
Copyright © 2011-2022 走看看