题意:给出n个点(构成一棵树),每个点包含u(直接父节点),rk(等级),t(权值)给出n个点(构成一棵树),每个点包含u(直接父节点),rk(等级),t(权值)给出n个点(构成一棵树),每个点包含u(直接父节点),rk(等级),t(权值)
求比i这个点rk值小的点的权值(t)之和求比i这个点rk值小的点的权值(t)之和求比i这个点rk值小的点的权值(t)之和
题解:dfs序+树状数组/线段树dfs序+树状数组 / 线段树dfs序+树状数组/线段树
用dfs序将这棵数怕平成区间,dfs时dp求出每个点对应的深度。结构体存每个点的信息,然后按照rk用dfs序将这棵数怕平成区间,dfs时dp求出每个点对应的深度。结构体存每个点的信息,然后按照rk用dfs序将这棵数怕平成区间,dfs时dp求出每个点对应的深度。结构体存每个点的信息,然后按照rk
从小到大排序,rk相同按深度从小到大排序(因为没求深度wa了无数发,如果不按深度排序,碰到rk相从小到大排序,rk相同按深度从小到大排序(因为没求深度wa了无数发,如果不按深度排序,碰到rk相从小到大排序,rk相同按深度从小到大排序(因为没求深度wa了无数发,如果不按深度排序,碰到rk相
的情况时,dfs后深度大的可能在深度小的区间前面,查询的时候就会使得答案变大),然后就是裸的求的情况时,dfs后深度大的可能在深度小的区间前面,查询的时候就会使得答案变大),然后就是裸的求的情况时,dfs后深度大的可能在深度小的区间前面,查询的时候就会使得答案变大),然后就是裸的求
前缀和树状数组前缀和树状数组前缀和树状数组
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x) x&-x;
#define debugint(name,x) printf("%s: %d\n",name,x);
#define debugstring(name,x) printf("%s: %s\n",name,x);
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 1e5+5;
const int mod = 1e9+7;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll in[maxn],out[maxn],tot,n,rk[maxn],t[maxn],dp[maxn],root;
ll sum[maxn],ans[maxn];
vector<int>ve[maxn];
struct node{
ll rk,t;
int id;
bool operator<(const node C)const{
if(rk == C.rk) return dp[id] < dp[C.id];
return rk < C.rk;
}
}tr[maxn],sv[maxn];
void dfsxu(int cur,int fa){
in[cur] = ++tot;
sv[tot] = tr[cur];
dp[cur] = dp[fa]+1;
for(int i = 0; i < ve[cur].size(); i++){
int v = ve[cur][i];
if(v == fa) continue;
dfsxu(v,cur);
}
out[cur] = tot;
}
void add(int x,ll val){
while(x < maxn){
sum[x] += val;
x += lowbit(x);
}
}
ll query(int x){
ll res = 0;
while(x > 0){
res += sum[x];
x -= lowbit(x);
}
return res;
}
int main() {
scanf("%lld",&n);
int u;
for(int i = 1; i <= n; i++){
scanf("%d%lld%lld",&u,&tr[i].rk,&tr[i].t);
tr[i].id = i;
if(u == -1) root = i;
else{
ve[u].push_back(i);
ve[i].push_back(u);
}
}
tot = 0;
dfsxu(root,-1);
sort(sv+1,sv+n+1);
for(int i = 1; i <= n; i++){
int pos = sv[i].id;
ll tmp = query(out[pos])-query(in[pos]);
ans[pos] = tmp;
add(in[pos],sv[i].t);
}
for(int i = 1; i <= n; i++)
printf("%lld\n",ans[i]);
}
有问题欢迎指出!有问题欢迎指出!有问题欢迎指出!