GYM 100827 I.Salary Inequity(线段树)

    xiaoxiao2021-03-25  103

    Description 一棵有向树,1是根,每个点有点权,两种操作: Q u:查询u节点为根节点的子树中权值最大值与最小值的差 R u x:给以u节点为根节点的子树所有点点权加上x Input 第一行一整数T表示用例组数,每组用例首先输入一整数n表示点数,之后n-1个数,第i个数表示i+1点的父亲节点,之后n个数c[i]表示每个点的点权,然后输入一整数q表示操作数,最后q行每行一种操作 (2<=n<=1e6,1<=m<=1e4,1<=c[i]<=1e3,1<=x<=1e3) Output 对于每次查询操作,输出结果 Sample Input 1 5 1 1 2 2 10 6 8 4 5 7 Q 2 Q 3 R 4 2 Q 2 Q 1 R 2 4 Q 1 Sample Output 2 0 1 5 2 Solution 求出每个点的dfs序后,两种操作分别变成查询区间最大值最小值以及区间更新,线段树即可 Code

    #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; #define INF 0x3f3f3f3f #define maxn 1111111 int T,n,q,ll[maxn],rr[maxn],index; vector<int>g[maxn]; void dfs(int u) { ll[u]=++index; for(int i=0;i<g[u].size();i++)dfs(g[u][i]); rr[u]=index; } #define ls (t<<1) #define rs ((t<<1)|1) int Max[maxn<<2],Min[maxn<<2],Plus[maxn<<2]; void build(int l,int r,int t) { Max[t]=Min[t]=Plus[t]=0; if(l==r)return ; int mid=(l+r)>>1; build(l,mid,ls),build(mid+1,r,rs); } void push_up(int t) { Max[t]=max(Max[ls],Max[rs]); Min[t]=min(Min[ls],Min[rs]); } void push_down(int t) { if(Plus[t]) { int tt=Plus[t]; Plus[t]=0; Max[ls]+=tt,Min[ls]+=tt,Plus[ls]+=tt; Max[rs]+=tt,Min[rs]+=tt,Plus[rs]+=tt; } } void update(int L,int R,int l,int r,int t,int v) { if(L<=l&&r<=R) { Min[t]+=v,Max[t]+=v,Plus[t]+=v; return ; } push_down(t); int mid=(l+r)>>1; if(L<=mid)update(L,R,l,mid,ls,v); if(R>mid) update(L,R,mid+1,r,rs,v); push_up(t); } int query_max(int L,int R,int l,int r,int t) { if(L<=l&&r<=R)return Max[t]; push_down(t); int ans=0; int mid=(l+r)>>1; if(L<=mid)ans=max(ans,query_max(L,R,l,mid,ls)); if(R>mid)ans=max(ans,query_max(L,R,mid+1,r,rs)); return ans; } int query_min(int L,int R,int l,int r,int t) { if(L<=l&&r<=R)return Min[t]; push_down(t); int ans=INF; int mid=(l+r)>>1; if(L<=mid)ans=min(ans,query_min(L,R,l,mid,ls)); if(R>mid)ans=min(ans,query_min(L,R,mid+1,r,rs)); return ans; } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); index=0; for(int i=1;i<=n;i++)g[i].clear(); for(int i=1;i<n;i++) { int fa; scanf("%d",&fa); g[fa].push_back(i+1); } dfs(1); build(1,n,1); for(int i=1;i<=n;i++) { int c; scanf("%d",&c); update(ll[i],ll[i],1,n,1,c); } scanf("%d",&q); while(q--) { char op[3]; int x,c; scanf("%s",op); if(op[0]=='Q') { scanf("%d",&x); printf("%d\n",query_max(ll[x],rr[x],1,n,1)-query_min(ll[x],rr[x],1,n,1)); } else { scanf("%d%d",&x,&c); update(ll[x],rr[x],1,n,1,c); } } } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-21092.html

    最新回复(0)