首页 > 代码库 > 【树状数组】Gym - 101147J - Whistle's New Car
【树状数组】Gym - 101147J - Whistle's New Car
题意就是对每个点i,统计在其子树内(不含自身),且depj-depi<=xj的点有多少个。
把点分别按照dep-x和dep进行排序,离线处理,
每次把dep-x小于等于当前dep值的点插入树状数组,就变成了询问dfs序在一个区间内的点有多少个,可以用树状数组轻松解决。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int f,C; void R(int &x){ C=0;f=1; for(;C<‘0‘||C>‘9‘;C=getchar())if(C==‘-‘)f=-1; for(x=0;C>=‘0‘&&C<=‘9‘;C=getchar())(x*=10)+=(C-‘0‘); x*=f; } typedef long long ll; #define N 500010 int T,n,a[N]; int v[N<<1],next[N<<1],w[N<<1],first[N],e; void AddEdge(int U,int V,int W) { v[++e]=V; w[e]=W; next[e]=first[U]; first[U]=e; } ll dep[N]; int Ls[N],Rs[N],tot; bool vis[N]; void dfs(int U) { vis[U]=1; Ls[U]=++tot; for(int i=first[U];i;i=next[i]) if(!vis[v[i]]) { dep[v[i]]=dep[U]+(ll)w[i]; dfs(v[i]); } Rs[U]=tot; } //struct Point //{ // ll v; // int p; //}t[N<<1]; //bool cmp(const Point &a,const Point &b) //{ // return a.v<b.v; //} struct Poin2 { ll v; int p; }all[N<<1]; bool cm2(const Poin2 &a,const Poin2 &b) { return a.v<b.v; } int anss[N]; int d[N]; void update(int p){for(;p<=n;p+=(p&(-p))) ++d[p];} int query(int p){int res=0; for(;p;p-=(p&(-p))) res+=d[p]; return res;} int main() { freopen("car.in","r",stdin); // freopen("car.out","w",stdout); int x,y,z; R(T); for(;T;--T) { e=tot=0; memset(v,0,sizeof(v)); memset(w,0,sizeof(w)); memset(next,0,sizeof(next)); memset(first,0,sizeof(first)); memset(vis,0,sizeof(vis)); memset(dep,0,sizeof(dep)); memset(d,0,sizeof(d)); R(n); for(int i=1;i<=n;++i) R(a[i]); for(int i=1;i<n;++i) { R(x); R(y); R(z); AddEdge(x,y,z); AddEdge(y,x,z); } dfs(1); // for(int i=1;i<=n;++i) // { // t[i].v=dep[i]-(ll)a[i]; // t[i].p=i; // } // for(int i=n+1;i<=n*2;++i) // { // t[i].v=dep[i-n]; // t[i].p=i; // } // sort(t+1,t+n*2+1,cmp); // int zy=1; // all[t[1].p].v=zy; // all[t[1].p].p=(t[1].p>n ? t[1].p-n : t[1].p); // for(int i=2;i<=n*2;++i) // { // if(t[i].v!=t[i-1].v) // ++zy; // all[t[i].p].v=zy; // all[t[i].p].p=(t[i].p>n ? t[i].p-n : t[i].p); // } for(int i=1;i<=n;++i) { all[i].v=dep[i]-(ll)a[i]; all[i].p=i; } for(int i=n+1;i<=n*2;++i) { all[i].v=dep[i-n]; all[i].p=i-n; } sort(all+1,all+n+1,cm2); sort(all+n+1,all+n*2+1,cm2); int j=1; for(int i=n+1;i<=n*2;++i) { while(all[j].v<=all[i].v && j<=n) { update(Ls[all[j].p]); ++j; } anss[all[i].p]=query(Rs[all[i].p])-query(Ls[all[i].p]); } for(int i=1;i<n;++i) printf("%d ",anss[i]); printf("%d\n",anss[n]); } return 0; }
【树状数组】Gym - 101147J - Whistle's New Car
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。