牛客练习赛6 B,D 题解

来源:互联网 发布:js控制浏览器最小宽度 编辑:程序博客网 时间:2024/06/02 06:07

比赛传送门
B:
首先不要把题想太复杂了, 只需要维护好几个值就OK了, 首先是5个数组
fa[x] 表示 x 的父亲是谁
son[x] 表示x有说多少个儿子
op[x] 表示x被操作的次数
a[x] 表示x的儿子对x的影响数
b[x] 表示x的孙子对x的影响数

有了这些的基础, 那么对于每次我们操作的点u的点权和res, 首先是他父亲对他的影响 res += a[fa[u]] + op[fa[u]]*2 ; (为什么*2好好想想)

其次:
res += (son[u] + 1) * op[u] + a[u] * 2 + b[u];
son[u] + 1 是指改变点u对它本身和其儿子的影响, 而a[u]表示儿子对它的影响, b[u]表示u的孙子对u的影响.

所以代码如下: (提醒下, 不知道为什么会T, 然后用了fastio, 直接到400ms, 读入挂真的猛)
AC Code

const int maxn = 1e5+5;int cas=1;int fa[maxn],son[maxn],op[maxn],a[maxn],b[maxn];struct FastIO{    static const int S = 2*100;    int wpos;    char wbuf[S];    FastIO() : wpos(0) {}    inline int xchar()    {        static char buf[S];        static int len = 0, pos = 0;        if (pos==len)            pos = 0, len = fread(buf, 1, S, stdin);        if (pos==len) exit(0);        return buf[pos ++];    }    inline int xint()    {        int s = 1, c = xchar(), x = 0;        while(c<=32) c = xchar();        if(c=='-') s = -1, c = xchar();        for(;'0'<=c && c<='9';c=xchar()) x = x*10+c-'0';        return x * s;    }    ~FastIO()    {        if(wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;    }}io;void solve(){    int n,m;    n = io.xint(); m = io.xint();    for(int i=1;i<n;i++) {        int u; u = io.xint();        fa[i+1] = u;        son[u]++;    }    ll ans = 0;    for(int i=1;i<=m;i++) {        int u; u = io.xint();        op[u] = (op[u] + 1) % mod;        ll res = 0;        if(fa[u]) {            int tmp = fa[u];            a[tmp] = (a[tmp] + 1) % mod;            res = (res + a[tmp] + op[tmp] + op[tmp]) % mod;        }        if(fa[fa[u]]) {            int tmp = fa[fa[u]];            b[tmp] = (b[tmp] + 1) % mod;            res = (res + op[tmp]) % mod;        }        res = (res + (son[u] + 1) * op[u] + a[u] + a[u] + b[u]) % mod;        ans = (ans + res * i % mod ) % mod;    }    cout << ans << endl;}

D:
其实是一道水题, 想好是排序后对应位置当然可以使答案最优就行了, 然后是赋值, 所以可以直接替换掉前x个最小的(前提是有这么多个)就行了…..

AC Code

const int maxn = 2e5+5;int cas=1;int a[maxn],b[maxn];void solve(){    int n,x,y;    scanf("%d%d%d",&n,&x,&y);    for(int i=1;i<=n;i++) {        scanf("%d",&a[i]);    }    for(int i=1;i<=n;i++) {        scanf("%d",&b[i]);    }    sort(a+1,a+1+n);    sort(b+1,b+1+n);    for(int i=1;i<=n&&i<=x;i++) {        if(a[i]<y) a[i] = y;    }    sort(a+1,a+1+n);    int ans = 0;    for(int i=1;i<=n;i++) {        ans = max(ans,b[i]-a[i]);    }    cout << ans << endl;}
原创粉丝点击