题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4605
题意:给一颗树,每个节点有个权值w[u],每个节点只有两个儿子或者没有儿子,从根节点放下一个小球,小球有一个权值X:
1.如果X=w[u],小球停止下落。
2.如果X<w[u],小球往左儿子和右儿子的概率都是1/2。
3.如果X>w[u],小球往左儿子的概率为1/7,往右儿子的概率为7/8。
现在有m个询问<v,x>,表示重量为x的小球到达v节点的概率。
首先离散化节点的权值。考虑从根节点到达v节点是一条路径,那么我们可以深度遍历树的每个节点,对于很多节点的询问都会经过相同的路径,因此我们可以保存前面的经过的点的重量的数目,因为左边和右边的情况不一样,所以分别存储左边和右边的数目和,这里用树状数组来优化。因为这里是对树来搜索,因此对询问离线化操作。
1 //STATUS:C++_AC_1125MS_8572KB 2 #include <functional> 3 #include <algorithm> 4 #include <iostream> 5 //#include <ext/rope> 6 #include <fstream> 7 #include <sstream> 8 #include <iomanip> 9 #include <numeric> 10 #include <cstring> 11 #include <cassert> 12 #include <cstdio> 13 #include <string> 14 #include <vector> 15 #include <bitset> 16 #include <queue> 17 #include <stack> 18 #include <cmath> 19 #include <ctime> 20 #include <list> 21 #include <set> 22 #include <map> 23 #pragma comment(linker,"/STACK:102400000,102400000") 24 using namespace std; 25 //using namespace __gnu_cxx; 26 //define 27 #define pii pair<int,int> 28 #define mem(a,b) memset(a,b,sizeof(a)) 29 #define lson l,mid,rt<<1 30 #define rson mid+1,r,rt<<1|1 31 #define PI acos(-1.0) 32 //typedef 33 typedef __int64 LL; 34 typedef unsigned __int64 ULL; 35 //const 36 const int N=100010,M=2000010; 37 const int INF=0x3f3f3f3f; 38 const int MOD=100000,STA=8000010; 39 const LL LNF=1LL<<60; 40 const double EPS=1e-8; 41 const double OO=1e15; 42 const int dx[4]={-1,0,1,0}; 43 const int dy[4]={0,1,0,-1}; 44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 45 //Daily Use ... 46 inline int sign(double x){return (x>EPS)-(x<-EPS);} 47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} 48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} 49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;} 50 template<class T> inline T Min(T a,T b){return a<b?a:b;} 51 template<class T> inline T Max(T a,T b){return a>b?a:b;} 52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);} 53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);} 54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));} 55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));} 56 //End 57 58 struct Node{ 59 int v,x,id; 60 }nod[N]; 61 int hs[N<<1],w[N],ans[N][2],g[N][2],vis[N<<1]; 62 int suml[N<<1],sumr[N<<1]; 63 int T,n,m,cnt; 64 vector<int> q[N]; 65 66 int binary(int l,int r,int tar) 67 { 68 int mid; 69 while(l<r){ 70 mid=(l+r)>>1; 71 if(hs[mid]<tar)l=mid+1; 72 else if(hs[mid]>tar)r=mid; 73 else return mid; 74 } 75 return -1; 76 } 77 78 inline int lowbit(int x) 79 { 80 return x&(-x); 81 } 82 83 void update(int *sum,int x,int val) 84 { 85 while(x<=cnt){ 86 sum[x]+=val; 87 x+=lowbit(x); 88 } 89 } 90 91 int getsum(int *sum,int x) 92 { 93 int ret=0; 94 while(x){ 95 ret+=sum[x]; 96 x-=lowbit(x); 97 } 98 return ret; 99 } 100 101 void dfs(int u) 102 { 103 int i,j,v,k,key; 104 for(i=0;i<q[u].size();i++){ 105 k=q[u][i]; 106 key=binary(1,cnt+1,nod[k].x); 107 if(vis[key]){ 108 ans[nod[k].id][0]=-1; 109 continue; 110 } 111 ans[nod[k].id][0]=getsum(sumr,key-1); 112 ans[nod[k].id][1]=getsum(suml,cnt)-getsum(suml,key) 113 +getsum(sumr,cnt)-getsum(sumr,key) 114 +(getsum(suml,key-1)+getsum(sumr,key-1))*3; 115 } 116 key=binary(1,cnt+1,w[u]); 117 if(g[u][0]){ 118 for(i=0;i<2;i++){ 119 update(i?sumr:suml,key,1); 120 vis[key]++; 121 dfs(g[u][i]); 122 update(i?sumr:suml,key,-1); 123 vis[key]--; 124 } 125 } 126 } 127 128 int main() 129 { 130 // freopen("in.txt","r",stdin); 131 int i,j,t,u,a,b; 132 scanf("%d",&T); 133 while(T--) 134 { 135 scanf("%d",&n); 136 j=1; 137 for(i=1;i<=n;i++){ 138 scanf("%d",&w[i]); 139 hs[j++]=w[i]; 140 } 141 scanf("%d",&t); 142 mem(g,0); 143 while(t--){ 144 scanf("%d%d%d",&u,&a,&b); 145 g[u][0]=a;g[u][1]=b; 146 } 147 scanf("%d",&m); 148 for(i=1;i<=n;i++)q[i].clear(); 149 for(i=1;i<=m;i++){ 150 scanf("%d%d",&nod[i].v,&nod[i].x); 151 nod[i].id=i; 152 hs[j++]=nod[i].x; 153 q[nod[i].v].push_back(i); 154 } 155 sort(hs+1,hs+j); 156 for(i=2,cnt=1;i<j;i++){ 157 if(hs[i]!=hs[cnt])hs[++cnt]=hs[i]; 158 } 159 160 mem(suml,0),mem(sumr,0); 161 mem(vis,0); 162 dfs(1); 163 164 for(i=1;i<=m;i++){ 165 if(ans[i][0]==-1) 166 printf("%d ",0); 167 else printf("%d %d ",ans[i][0],ans[i][1]); 168 } 169 } 170 return 0; 171 }