hdu 4605-Magic Ball Game(树状数组)

来源:互联网 发布:淘宝街拍用什么镜头 编辑:程序博客网 时间:2024/05/19 13:24

题目大意:

给你一棵二叉树,每个节点有一个w值,现在有一颗小球,值为x,从根节点往下掉,如果w==x,那么它就会停止;如果w>x,那么它往左、右儿子的概率都是1、2;如果w<x,那么它往左儿子的概率是1/8,右儿子是7/8。现在给你q个询问,问你值为x的球道达节点u的概率为多少。

思路:

用树状数组离线处理。

摘录学长说的:

从一根节点u到一个点v存在的是唯一的一条确定的道路。我们只需要它在这条路上往左拐的情况中w的值(X可能大于该点的权值grtL,可能小于该点的权值lessL) 往右拐的情况中w的值(X可能大于该点的权值grtR,可能小于该点的权值lessR)  那么对于这个点的询问我们就可以知道:

x = grtR(只有它对7有贡献)  y = (lessL + lessR) + (grtL + grtR)*3; ”

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h>#include<iostream>#include<vector>#include<algorithm>#include<string.h>using namespace std;#define maxn 100005struct list{int l,r;int w;}node[maxn];int fs[maxn*2];int fss[maxn*2];struct qq{int x;int id;}xx;vector<qq>num[maxn];int ans[maxn][2];int sum[maxn][2];int w[maxn];int n,m,q,len;int lowbit(int x){ return (x&(-x));}int search(int l,int r,int w){while(l<r){int mid=(l+r)/2;if(fs[mid]==w)return mid;if(fs[mid]<w)l=mid+1;else r=mid;}}void add(int x,int bs,int num){for(;x<len;x+=lowbit(x)){sum[x][bs]+=num;}}int allsum(int s,int bs){int ss;ss=0;while(s>0){ss+=sum[s][bs];s=s-lowbit(s);}return ss;}void dfs(int x){int s;s=num[x].size();for(int i=0;i<s;i++){xx=num[x][i];int z,id;z=search(1,len,xx.x);id=xx.id;if(allsum(z,0)-allsum(z-1,0)+allsum(z,1)-allsum(z-1,1)>0){ans[id][0]=-1;continue;}int ll,lr,rl,rr;ll=allsum(len-1,0)-allsum(z,0);rl=allsum(z,0);lr=allsum(len-1,1)-allsum(z,1);rr=allsum(z,1);ans[id][0]=rr;ans[id][1]=(rl+rr)*3+ll+lr;}s=search(1,len,node[x].w);if(node[x].l!=-1){add(s,0,1);dfs(node[x].l);add(s,0,-1);}if(node[x].r!=-1){add(s,1,1);dfs(node[x].r);add(s,1,-1);}}int main(){int T,a,b,c,i;cin>>T;while(T--){cin>>n;int ll=1;memset(fs,0,sizeof(fs));memset(ans,0,sizeof(ans));memset(fss,0,sizeof(fss));for (i = 1; i <= n; ++i) node[i].l = node[i].r = node[i].w = -1;for(i=1;i<=n;i++){num[i].clear();scanf("%d",&w[i]);node[i].w=w[i];fss[ll++]=w[i];}cin>>m;for(i=1;i<=m;i++){scanf("%d%d%d",&a,&b,&c);node[a].l=b;node[a].r=c;}cin>>q;for(i=1;i<=q;i++){scanf("%d%d",&a,&b);fss[ll++]=b;xx.id=i;xx.x=b;num[a].push_back(xx);}len=1;sort(fss,fss+ll);for(i=1;i<ll;i++)if(fss[i]!=fss[i-1])fs[len++]=fss[i];dfs(1);for(i=1;i<=q;i++){if(ans[i][0]==-1)printf("0\n");else printf("%d %d\n",ans[i][0],ans[i][1]);}}return 0;}


原创粉丝点击