zoukankan      html  css  js  c++  java
  • 【BZOJ】3683: Falsita

    题解

    这道题维护方法比较简单,也有点奇妙

    我们可以很容易求出经过所有点的路径条数,和初始时分子的大小

    然后单点修改的时候,相当于给当前点(v)加上(delta * (siz[v] - 1))

    (v)到根的路径上每个祖先都要加上设(t)(k)在路径上的儿子,(delta * (siz[k] - siz[t]))
    如果想把这种操作快速修改的话,我们把这个操作放到重链上,这样只有重链顶端的父亲需要特殊处理,剩下的值都已经计算好了,用一个标记在线段树上维护就好

    然后考虑区间加,对于修改的这个(v),我们相当于加上(delta * 2 * path[v]),而v所有的儿子以及后代都是一样的操作,所以我们维护第二个标记用来乘上每个节点的(path[u] * 2)

    对于(v)的祖先,就相当于单点修改增加了(siz[v] * delta)

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define mp make_pair
    #define pb push_back
    //#define ivorysi
    #define MAXN 300005
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;char c = getchar();T f = 1;
        while(c < '0' || c > '9') {
        	if(c == '-') f = -1;
        	c = getchar();
        }
        while(c >= '0' && c <= '9') {
        	res = res * 10 + c - '0';
        	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
        	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    struct node {
        int to,next;
    }E[MAXN * 2];
    int N,head[MAXN],sumE,M;
    int siz[MAXN],dfn[MAXN],son[MAXN],idx,top[MAXN],fa[MAXN],dep[MAXN];
    int64 path[MAXN],tag[MAXN],val[MAXN],w[MAXN],sum[MAXN];
    void add(int u,int v) {
        E[++sumE].to = v;
        E[sumE].next = head[u];
        head[u] = sumE;
    }
    struct segment_tree {
        struct node {
            int L,R;
            pair<int64,int64> d;
        }tr[MAXN * 4];
        pair<int64,int64> Merge(pair<int64,int64> a,pair<int64,int64> b) {
            return mp(a.fi + b.fi,a.se + b.se);
        }
        void push_down(int u) {
            tr[u << 1].d = Merge(tr[u].d,tr[u << 1].d);
            tr[u << 1 | 1].d = Merge(tr[u].d,tr[u << 1 | 1].d);
            tr[u].d = mp(0,0);
        }
        void build(int u,int L,int R) {
            tr[u].L = L;tr[u].R = R;
            tr[u].d = mp(0,0);
            if(L == R) return;
            int mid = (L + R) >> 1;
            build(u << 1,L,mid);
            build(u << 1 | 1,mid + 1,R);
        }
        void Add(int u,int l,int r,pair<int64,int64> d) {
            if(tr[u].L == l && tr[u].R == r) {
                tr[u].d = Merge(d,tr[u].d);
                return;
            }
            push_down(u);
            int mid = (tr[u].L + tr[u].R) >> 1;
            if(r <= mid) Add(u << 1,l,r,d);
            else if(l > mid) Add(u << 1 | 1,l,r,d);
            else {Add(u << 1,l,mid,d);Add(u << 1 | 1,mid + 1,r,d);}
        }
        pair<int64,int64> Query(int u,int pos) {
            if(tr[u].L == tr[u].R) return tr[u].d;
            push_down(u);
            int mid = (tr[u].L + tr[u].R) >> 1;
            if(pos <= mid) return Query(u << 1,pos);
            else return Query(u << 1 | 1,pos);
        }
    }Tr;
    
    void Add_Path(int u,int64 v) {
        while(u) {
            int t = top[u];
            if(dfn[t] <= dfn[u] - 1) Tr.Add(1,dfn[t],dfn[u] - 1,mp(v,0));
            if(fa[t]) val[fa[t]] += (siz[fa[t]] - siz[t]) * v;
            u = fa[t];
        }
    }
    
    
    void dfs1(int u) {
        siz[u] = 1;
        dep[u] = dep[fa[u]] + 1;
        sum[u] = w[u];
        dfn[u] = ++idx;
        for(int i = head[u] ; i ; i = E[i].next) {
            int v = E[i].to;
            if(v != fa[u]) {
                fa[v] = u;
                dfs1(v);
                sum[u] += sum[v];
                path[u] += siz[u] * siz[v];
                siz[u] += siz[v];
                if(siz[v] > siz[son[u]]) son[u] = v;
            }
        }
        val[u] += w[u] * (siz[u] - 1);
        for(int i = head[u] ; i ;  i = E[i].next) {
            int v = E[i].to;
            if(v != fa[u]) {
                val[u] += sum[v] * (siz[u] - siz[v]);
            }
        }
        tag[u] = siz[u] - siz[son[u]];
    }
    void dfs2(int u) {
        if(!top[u]) {top[u] = u;}
        if(son[u]) {
            top[son[u]] = top[u];
            dfs2(son[u]);
        }
        for(int i = head[u] ; i ; i = E[i].next) {
            int v = E[i].to;
            if(v != fa[u] && v != son[u]) {
                dfs2(v);
            }
        }
    }
    void Init() {
        read(N);read(M);
        int p;
        for(int i = 2 ; i <= N ; ++i) {
            read(p);
            add(p,i);add(i,p);
        }
        for(int i = 1 ; i <= N ; ++i) read(w[i]);
        dfs1(1);dfs2(1);
        Tr.build(1,1,N);
    }
    
    void Solve() {
        char op[5];
        int u;int64 v;
        while(M--) {
            scanf("%s",op + 1);
            if(op[1] == 'S') {
                read(u);read(v);
                val[u] += (siz[u] - 1) * v;
                Add_Path(u,v);
            }
            else if(op[1] == 'M'){
                read(u);read(v);
                Tr.Add(1,dfn[u],dfn[u] + siz[u] - 1,mp(0,v));
                if(fa[u]) val[fa[u]] += siz[u] * v * (siz[fa[u]] - siz[u]);
                Add_Path(fa[u],siz[u] * v);
            }
            else {
                read(u);
                pair<int64,int64> res = Tr.Query(1,dfn[u]);
                int64 up = res.fi * tag[u] + res.se * 2 * path[u] + val[u];
                int64 down = path[u];
                printf("%.6lf
    ",(db)up / down);
            }
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Init();
        Solve();
        return 0;
    }
    
  • 相关阅读:
    几个新角色:数据科学家、数据分析师、数据(算法)工程师
    人类投资经理再也无法击败电脑的时代终将到来了...
    Action Results in Web API 2
    Multiple actions were found that match the request in Web Api
    Routing in ASP.NET Web API
    how to create an asp.net web api project in visual studio 2017
    网站漏洞扫描工具
    How does asp.net web api work?
    asp.net web api history and how does it work?
    What is the difference between a web API and a web service?
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9877758.html
Copyright © 2011-2022 走看看