zoukankan      html  css  js  c++  java
  • 【树状数组】Gym

    题意就是对每个点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
    ",anss[n]);
    	  }
    	return 0;
    }
  • 相关阅读:
    最小覆盖点集模板
    NSCache使用常见错误
    stl变易算法(一)
    web.xml(8)_jsp-config
    大话设计模式—中介者模式
    HTML5开发移动web应用——SAP UI5篇(9)
    BZOJ 1588 HNOI2002 营业额统计 裸Treap
    php实现Bloom Filter
    华为上机之四
    【转】我的电脑最近忽然开不了机,启动修复也无法修复,win7系统。开机的时候如果不点启动修复直接正常启动
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6347783.html
Copyright © 2011-2022 走看看