题意:每个点有一个权值 求每个节点的子树中比其权值大的节点数
线段树合并模板题
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<‘=‘<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) ///////////////////////////////////// const int N=1e5+100; int t[N<<5],b[N],lson[N<<5],rson[N<<5],T[N],pos,head[N],ncnt,n,ans[N],node[N],nn; struct Edge{int to,nex;}edge[N<<1]; void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;} void upnode(int x,int l,int r,int &pos) { if(!pos)pos=++ncnt; if(l==r){t[pos]++;return ;} int m=(l+r)>>1; if(x<=m)upnode(x,l,m,lson[pos]); else upnode(x,m+1,r,rson[pos]); t[pos]=t[lson[pos]]+t[rson[pos]]; } int qsum(int L,int R,int l,int r,int pos) { if(L<=l&&r<=R)return t[pos]; int m=(l+r)>>1;int ans=0; if(L<=m)ans+=qsum(L,R,l,m,lson[pos]); if(R>m)ans+=qsum(L,R,m+1,r,rson[pos]); return ans; } int Merge(int a,int b,int l,int r) { if(!a)return b; if(!b)return a; if(l==r) { t[a]+=t[b]; return a; } int m=(l+r)>>1; lson[a]=Merge(lson[a],lson[b],l,m); rson[a]=Merge(rson[a],rson[b],m+1,r); t[a]=t[lson[a]]+t[rson[a]]; return a; } void dfs(int x) { for(int i=head[x];i;i=edge[i].nex) { int v=edge[i].to; dfs(v); T[x]=Merge(T[x],T[v],1,nn); } ans[x]=qsum(node[x],nn,1,nn,T[x]); upnode(node[x],1,nn,T[x]); } int main() { scanf("%d",&n); rep(i,1,n) scanf("%d",&node[i]),b[i]=node[i],T[i]=i,ncnt++; sort(b+1,b+1+n); nn=unique(b+1,b+1+n)-b-1; rep(i,1,n)node[i]=lower_bound(b+1,b+1+nn,node[i])-b; rep(i,2,n) { int x;scanf("%d",&x);add(x,i); } dfs(1); rep(i,1,n) printf("%d\n",ans[i]); return 0; }
其实也可以树状数组秒解
递归子树的时候先减去树状数组原有的信息即可
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<‘=‘<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) ///////////////////////////////////// const int N=1e5+100; int t[N<<5],b[N],lson[N<<5],rson[N<<5],T[N],pos,head[N],ncnt,n,ans[N],node[N],nn; struct Edge{int to,nex;}edge[N<<1]; void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;} void upnode(int x,int l,int r,int &pos) { if(!pos)pos=++ncnt; if(l==r){t[pos]++;return ;} int m=(l+r)>>1; if(x<=m)upnode(x,l,m,lson[pos]); else upnode(x,m+1,r,rson[pos]); t[pos]=t[lson[pos]]+t[rson[pos]]; } int qsum(int L,int R,int l,int r,int pos) { if(L<=l&&r<=R)return t[pos]; int m=(l+r)>>1;int ans=0; if(L<=m)ans+=qsum(L,R,l,m,lson[pos]); if(R>m)ans+=qsum(L,R,m+1,r,rson[pos]); return ans; } int Merge(int a,int b,int l,int r) { if(!a)return b; if(!b)return a; if(l==r) { t[a]+=t[b]; return a; } int m=(l+r)>>1; lson[a]=Merge(lson[a],lson[b],l,m); rson[a]=Merge(rson[a],rson[b],m+1,r); t[a]=t[lson[a]]+t[rson[a]]; return a; } void dfs(int x) { for(int i=head[x];i;i=edge[i].nex) { int v=edge[i].to; dfs(v); T[x]=Merge(T[x],T[v],1,nn); } ans[x]=qsum(node[x],nn,1,nn,T[x]); upnode(node[x],1,nn,T[x]); } int main() { scanf("%d",&n); rep(i,1,n) scanf("%d",&node[i]),b[i]=node[i],T[i]=i,ncnt++; sort(b+1,b+1+n); nn=unique(b+1,b+1+n)-b-1; rep(i,1,n)node[i]=lower_bound(b+1,b+1+nn,node[i])-b; rep(i,2,n) { int x;scanf("%d",&x);add(x,i); } dfs(1); rep(i,1,n) printf("%d\n",ans[i]); return 0; }
原文地址:https://www.cnblogs.com/bxd123/p/11411753.html
时间: 2024-10-24 03:50:10