zoukankan      html  css  js  c++  java
  • 【Usaco2017 Jan】Promotion Counting(树上差分+树状数组/线段树合并)

    传送门

    %%%ldxldx神仙线段树合并

    本来想练练线段树合并的,但是看了看题就树上差分秒切了

    考虑到我们维护一个权值为下标的树状数组

    每次dfsdfs一个点就updateupdate这个点

    每到一个点先记录一下目前比他大的点有多少个

    dfsdfs完他的儿子后再查询一下现在比他大的点有多少个

    相减就是答案了

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=100005;
    int tr[N],a[N],b[N],num,adj[N],ans[N],n,cnt,nxt[N<<1],to[N<<1];
    inline void addedge(int u,int v){
    	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
    }
    inline void init(){
    	sort(b+1,b+n+1);
    	num=unique(b+1,b+n+1)-b-1;
    	for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+num+1,a[i])-b;
    }
    inline int lowbit(int x){
    	return (x&(-x));
    }
    inline void update(int pos){
    	for(;pos<=n;pos+=lowbit(pos))tr[pos]+=1;
    }
    inline int query(int pos,int res=0){
    	for(;pos;pos-=lowbit(pos))res+=tr[pos];
    	return res;
    }
    void dfs(int u,int fa){
    	update(a[u]);
    	int pre=query(num)-query(a[u]);
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==fa)continue;
    		dfs(v,u);	
    	}
    	int now=query(num)-query(a[u]);
    	ans[u]=now-pre;
    }
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++)a[i]=b[i]=read();
    	init();
    	for(int i=2;i<=n;i++){
    		int f=read();addedge(f,i),addedge(i,f);
    	}
    	dfs(1,0);
    	for(int i=1;i<=n;i++)cout<<ans[i]<<'
    ';
    }
    
  • 相关阅读:
    pyspark使用及原理
    谷歌地图聚合点使用(GoogleMaps MarkerCluster)
    struts2升级到2.5的配置
    二进制反码补码
    进制转换
    JAVA基础第一章
    TypeError: unhashable type: 'list' 如何解决?
    剪辑模板
    Mysql三天入门(三) 数据库设计的三范式
    Mysql三天入门(三) DBA命令
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366353.html
Copyright © 2011-2022 走看看