• NC14393 点权和(思维)


    这种题肯定不会是暴力枚举,多半考虑是贡献

    首先我们要想清楚的是,我每次操作,会对哪些节点产生影响,答案又是从哪些节点更新而来

    很显然我们会从儿子,自身,父亲这三个角度去思考问题。

    所以我们会设计状态 now[]表示自身被操作的次数,a[],表示被儿子影响的次数,b[]表示的是被孙子操作的次数,in[]表示的是儿子个数。

    为什么这里会出现孙子呢,因为孙子+1,儿子+1,那么当答案的时候,儿子的值变化了,所以答案也变化了。

    为什么不用专门设计父亲呢?因为所有的父亲都是别人的儿子,所以这样的状态足以,不然就更加复杂了。

    假如我们对当前点进行更新,那么我们可以更新:

    当前点的权值,别的点的儿子影响,孙子影响。

    具体解释看代码,很多不同的答案都是对的,只要能表达清楚就行

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    const int mod=19260817;
    ll p[N],a[N],b[N];
    ll in[N];
    ll now[N];
    int main(){
        int n,m;
        cin>>n>>m;
        int i;
        for(i=2;i<=n;i++){
            int x;
            scanf("%d",&x);
            in[x]++;
            p[i]=x;
        }
        ll res=0;
        for(i=1;i<=m;i++){
            int x;
            scanf("%d",&x);
            now[x]++;//当前操作+1
            ll ans=0;
            if(p[x]){
                ll t=p[x];
                a[t]++;//父亲被自己影响+1
                ans=(ans+now[t]*2ll+a[t])%mod;//父亲的操作要×2,因为父亲和自己都加了1,再加上父亲被自己影响的次数
            }
            if(p[p[x]]){
                ll t=p[p[x]];
                ans=(ans+now[t])%mod;//爷爷的操作影响
                b[t]++;//爷爷被自己的影响
            }
            ans=(ans+(in[x]+1)%mod*now[x]%mod+a[x]*2+b[x])%mod;//自己操作数的贡献,以及儿子对儿子和自己的贡献以及孙子的贡献
            res=(res+ans*i+mod)%mod;
        }
        cout<<res<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    prometheus+alertmanage+grafana安装部署
    HAproxy
    redis安装部署
    rsync+inotify实现实时同步
    简单的计算功能,还需要优化
    python3配置文件的增删改查,记录一下
    一个简单的购物商城,记录一下。
    python函数参数
    python list内部功能记录
    python3 str各个功能记录
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12683783.html
Copyright © 2020-2023  润新知