HDU 4605 Magic Ball Game 树上主席树
2015-04-10 10:50
302 查看
用两颗主席树分别存大小为p的球的个数,还有就是处于右儿子的大小为p的个数即可,然后就是简单主席树。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int maxn=100005; struct pi{ int lson; int rson; int sum; }pp[maxn*18*2]; int root[2][maxn],tot,a[maxn],b[maxn],pa[maxn]; int ll[maxn],rr[maxn]; void build(int cnt,int l,int r){ pp[cnt].sum=0; if(l==r) return ; int mid=(l+r)/2; pp[cnt].lson=tot+1; tot++; build(tot,l,mid); pp[cnt].rson=tot+1; tot++; build(tot,mid+1,r); } void merg(int qq,int cnt,int n,int p,int k){ int le=1,ri=n,mid; while(le<=ri){ pp[cnt]=pp[qq]; mid=(le+ri)/2; pp[cnt].sum+=k; if(le==ri) return ; if(p<=mid){ pp[cnt].lson=tot+1; tot++; cnt=tot; qq=pp[qq].lson; ri=mid; } else{ pp[cnt].rson=tot+1; tot++; cnt=tot; qq=pp[qq].rson; le=mid+1; } } } int query(int cnt,int le,int ri,int l,int r){ if(le>=l&&ri<=r){ return pp[cnt].sum; } int s=0; int mid=(le+ri)/2; if(l<=mid) s+=query(pp[cnt].lson,le,mid,l,r); if(r>mid) s+=query(pp[cnt].rson,mid+1,ri,l,r); return s; } void dfs(int u,int n){ if(ll[u]==-1) return ; root[0][ll[u]]=tot+1; tot++; merg(root[0][u],tot,n,a[ll[u]],1); root[0][rr[u]]=tot+1; tot++; merg(root[0][u],tot,n,a[rr[u]],1); root[1][ll[u]]=tot+1; tot++; merg(root[1][u],tot,n,a[ll[u]],0); root[1][rr[u]]=tot+1; tot++; merg(root[1][u],tot,n,a[u],1); dfs(ll[u],n); dfs(rr[u],n); } int main() { int i,n,m,t; cin>>t; while(t--){ cin>>n; for(i=1;i<=n;i++){ scanf("%d",&a[i]); b[i]=a[i]; } sort(b+1,b+1+n); for(i=1;i<=n;i++){ a[i]=(int)(lower_bound(b+1,b+1+n,a[i])-b); } memset(ll,-1,sizeof(ll)); memset(rr,-1,sizeof(rr)); cin>>m; pa[1]=0; for(i=0;i<m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); pa[b]=pa[c]=a; ll[a]=b; rr[a]=c; } tot=0; root[0][0]=tot; build(tot,1,n); root[1][0]=tot+1; tot++; build(tot,1,n); root[0][1]=tot+1; tot++; merg(root[0][0],root[0][1],n,a[1],1); root[1][1]=tot+1; tot++; merg(root[1][0],root[1][1],n,a[1],0); dfs(1,n); cin>>m; for(i=0;i<m;i++){ int a,bb; scanf("%d%d",&a,&bb); int p=lower_bound(b+1,b+1+n, bb)-b; if(p<=n&&b[p]==bb){ if(query(root[0][pa[a]],1,n,p,p)){ printf("0\n"); continue; } } int s=0,s1=0; if(p>1){ s+=3*query(root[0][pa[a]],1,n,1,p-1); s1+=query(root[1][a],1,n,1,p-1); } if(p<=n&&b[p]==bb){ if(p<n) s+=query(root[0][pa[a]],1,n,p+1,n); } else{ if(p<=n){ s+=query(root[0][pa[a]],1,n,p,n); } } printf("%d %d\n",s1,s); } } }
相关文章推荐
- HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)
- HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)
- hdu 4605 Magic Ball Game(主席树学习第二弹)
- HDU 4605 Magic Ball Game 主席树
- hdu 4605:Magic Ball Game(主席树或者离线)
- HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)
- HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)
- HDU 4605 Magic Ball Game 树状数组
- HDU 4605 Magic Ball Game 树状数组
- HDU 4605 Magic Ball Game
- hdu 4605 Magic Ball Game(离线+树状数组)
- 2013 多校第一场 hdu 4605 Magic Ball Game
- HDU-4605 Magic Ball Game 树状数组+离散+dfs
- hdu 4605 Magic Ball Game
- hdu 4605 Magic Ball Game
- Magic Ball Game - HDU 4605 树状数组
- HDU 4605 Magic Ball Game(离线算法)
- hdu 4605-Magic Ball Game(树状数组)
- HDU 4605 Magic Ball Game 树状数组
- HDU 4605 Magic Ball Game(离线、BIT)