HDU-4605 Magic Ball Game 树状数组+离散+dfs
2013-07-28 18:09
405 查看
题目链接: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节点是一条路径,那么我们可以深度遍历树的每个节点,对于很多节点的询问都会经过相同的路径,因此我们可以保存前面的经过的点的重量的数目,因为左边和右边的情况不一样,所以分别存储左边和右边的数目和,这里用树状数组来优化。因为这里是对树来搜索,因此对询问离线化操作。
题意:给一颗树,每个节点有个权值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节点是一条路径,那么我们可以深度遍历树的每个节点,对于很多节点的询问都会经过相同的路径,因此我们可以保存前面的经过的点的重量的数目,因为左边和右边的情况不一样,所以分别存储左边和右边的数目和,这里用树状数组来优化。因为这里是对树来搜索,因此对询问离线化操作。
//STATUS:C++_AC_1125MS_8572KB #include <functional> #include <algorithm> #include <iostream> //#include <ext/rope> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cstring> #include <cassert> #include <cstdio> #include <string> #include <vector> #include <bitset> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <list> #include <set> #include <map> #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; //using namespace __gnu_cxx; //define #define pii pair<int,int> #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define PI acos(-1.0) //typedef typedef __int64 LL; typedef unsigned __int64 ULL; //const const int N=100010,M=2000010; const int INF=0x3f3f3f3f; const int MOD=100000,STA=8000010; const LL LNF=1LL<<60; const double EPS=1e-8; const double OO=1e15; const int dx[4]={-1,0,1,0}; const int dy[4]={0,1,0,-1}; const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //Daily Use ... inline int sign(double x){return (x>EPS)-(x<-EPS);} template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} template<class T> inline T lcm(T a,T b,T d){return a/d*b;} template<class T> inline T Min(T a,T b){return a<b?a:b;} template<class T> inline T Max(T a,T b){return a>b?a:b;} template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);} template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);} template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));} template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));} //End struct Node{ int v,x,id; }nod ; int hs[N<<1],w ,ans [2],g [2],vis[N<<1]; int suml[N<<1],sumr[N<<1]; int T,n,m,cnt; vector<int> q ; int binary(int l,int r,int tar) { int mid; while(l<r){ mid=(l+r)>>1; if(hs[mid]<tar)l=mid+1; else if(hs[mid]>tar)r=mid; else return mid; } return -1; } inline int lowbit(int x) { return x&(-x); } void update(int *sum,int x,int val) { while(x<=cnt){ sum[x]+=val; x+=lowbit(x); } } int getsum(int *sum,int x) { int ret=0; while(x){ ret+=sum[x]; x-=lowbit(x); } return ret; } void dfs(int u) { int i,j,v,k,key; for(i=0;i<q[u].size();i++){ k=q[u][i]; key=binary(1,cnt+1,nod[k].x); if(vis[key]){ ans[nod[k].id][0]=-1; continue; } ans[nod[k].id][0]=getsum(sumr,key-1); ans[nod[k].id][1]=getsum(suml,cnt)-getsum(suml,key) +getsum(sumr,cnt)-getsum(sumr,key) +(getsum(suml,key-1)+getsum(sumr,key-1))*3; } key=binary(1,cnt+1,w[u]); if(g[u][0]){ for(i=0;i<2;i++){ update(i?sumr:suml,key,1); vis[key]++; dfs(g[u][i]); update(i?sumr:suml,key,-1); vis[key]--; } } } int main() { // freopen("in.txt","r",stdin); int i,j,t,u,a,b; scanf("%d",&T); while(T--) { scanf("%d",&n); j=1; for(i=1;i<=n;i++){ scanf("%d",&w[i]); hs[j++]=w[i]; } scanf("%d",&t); mem(g,0); while(t--){ scanf("%d%d%d",&u,&a,&b); g[u][0]=a;g[u][1]=b; } scanf("%d",&m); for(i=1;i<=n;i++)q[i].clear(); for(i=1;i<=m;i++){ scanf("%d%d",&nod[i].v,&nod[i].x); nod[i].id=i; hs[j++]=nod[i].x; q[nod[i].v].push_back(i); } sort(hs+1,hs+j); for(i=2,cnt=1;i<j;i++){ if(hs[i]!=hs[cnt])hs[++cnt]=hs[i]; } mem(suml,0),mem(sumr,0); mem(vis,0); dfs(1); for(i=1;i<=m;i++){ if(ans[i][0]==-1) printf("%d\n",0); else printf("%d %d\n",ans[i][0],ans[i][1]); } } return 0; }
相关文章推荐
- 2013 多校联合 F Magic Ball Game (hdu 4605)
- hdu 4605 Magic Ball Game(主席树学习第二弹)
- hdu 4605 Magic Ball Game
- HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)
- 2013 多校联合 F Magic Ball Game (hdu 4605)
- hdu 4605:Magic Ball Game(主席树或者离线)
- HDU 4605 Magic Ball Game 树状数组
- Magic Ball Game - HDU 4605 树状数组
- hdu 4605 Magic Ball Game
- 2013 多校第一场 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(离线、BIT)
- HDU 4605 Magic Ball Game
- HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)
- HDU 4605 Magic Ball Game 树状数组
- hdu 4605 Magic Ball Game(离线+树状数组)