求调
查看原帖
求调
507374
sqrtqwq楼主2023/10/3 20:01
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000005;
struct edge
{
    int to,nxt;
}e[maxn];
int head[maxn],tot;
void add_edge(int u,int v)
{
    e[++tot].nxt = head[u];
    e[tot].to = v;
    head[u] = tot;
}
int in[maxn],out[maxn];
int n,m;
int cnt,ans[maxn];//离线算法
priority_queue<pair<int,int>,vector<pair<int,int>>, greater<pair<int,int>> > Q;
struct Query
{
    int u,x,id;
    bool operator <(const Query &a) const
    {
        return x < a.x;
    }
}q[maxn];
void dfs(int u)
{
    in[u] = ++cnt;
    for(int i = head[u];i;i = e[i].nxt)
    {
        dfs(e[i].to);
    }
    out[u] = cnt;
}
int fa[maxn];
int Find(int u)
{
    if(u == fa[u])
    {
        return u;
    }
    return fa[u] = Find(fa[u]);
}

struct BIT
{
    int c[maxn];
    int lowbit(int x)
    {
        return x & (-x);
    }
    void update(int x, int d)
    {
		for(int i = x; i <= n; i += lowbit(i))
        {
            c[i] += d;
        }
	}
	int query(int x)
    {
		int sum = 0;
		for (int i = x; i; i -= lowbit(i))
        {
            sum += c[i];
        }
		return sum;
	}
}sum,siz;

bool del[maxn];
int f[maxn];

void change(int u,int x)
{
    while(u != 1)//向上打通
    {
        del[u] = 1;
        int v = Find(f[u]);
        int sumu = sum.query(out[u]) - sum.query(in[u] - 1),sizu = siz.query(out[u]) - siz.query(in[u] - 1);
        if(f[v])
        {
            sum.update(in[f[v]],-sumu);
            siz.update(in[f[v]],-sizu);
        }
        fa[u] = v;
        int sumv = sum.query(out[v]) - sum.query(in[v] - 1),sizv = siz.query(out[v]) - siz.query(in[v] - 1);
        if (sizv * x + sumv <= 0)
        {
			Q.push({sumv > 0 ? -sumv / sizv : (-sumv + sizv - 1) / sizv, v});
			break;
		}
        u = v;
    }
}

int main()
{
    cin >> n >> m;
    for(int i = 1;i <= n;i++)
    {
        fa[i] = i;//并查集初始化
    }
    for(int i = 2;i <= n;i++)
    {
        cin >> f[i];
        add_edge(i,f[i]);
    }
    dfs(1);
    del[1] = 1;
    for(int i = 1,x;i <= n;i++)
    {
        cin >> x;
        Q.push({-x,i});
        sum.update(in[i],x);
        siz.update(in[i],1);
        if(i != 1)
        {
            sum.update(in[f[i]],-x);
            siz.update(in[f[i]],-1);
        }
    }
    // sum.update(1,1);
    for(int i = 1;i <= m;i++)
    {
        cin >> q[i].u >> q[i].x;
        q[i].id = i;
    }
    sort(q + 1,q + m + 1);
    for(int i = 1;i <= m;i++)
    {
        while(!Q.empty() && Q.top().first <= q[i].x)
        {
            int u = Q.top().second;
            Q.pop();
            if(del[u])
            {
                continue;
            }
            change(u,q[i].x);
        }
        ans[q[i].id] = (siz.query(out[q[i].u]) - siz.query(in[q[i].u])) * q[i].x + sum.query(out[q[i].u]) - sum.query(in[q[i].u]);
    }
    for(int i = 1;i <= m;i++)
    {
        cout << ans[i] << '\n';
    }
    return 0;
}

提交记录

2023/10/3 20:01
加载中...