hdu4605 Magic Ball Game(树状数组)
来源:互联网 发布:工控机软件开发 编辑:程序博客网 时间:2024/06/06 16:54
题目链接:点这里!!!!
题意:
给定一棵N(N<=1e5)节点的树,每个节点要么有两个儿子(左右两个儿子),要么没有儿子,每个节点有一个权值w[i]。
一个权值为X球从根节点开始下落,每落到一个节点的时候,
1.如果X=W[i],或者没有儿子节点了,球停止下落。
2.如果X<W[i],球各有1/2的概率落到左右儿子节点。
3.如果X>W[i],球有1/8的概率落到左儿子,有7/8的概率落到右儿子。
给你q(q<=1e5)个询问,询问中包含v,x。问你权值为x的球从根节点(根节点是1)落到v节点的概率是多少。(落不到输出0,否则概率用7^x/2^y表示,即输出x和y就可以。)
题解:
1、这道题我们可以对所有询问离线,相当于求当前节点到根节点的路径上有多少数大于它,有多少数小于它,有多少数等于它,我们可以直接用树状树状实现。
2、从根节点开始dfs,到达x节点时,取出其中的询问,树状数组里存的是根节点到father[x]中的权值,我可以快速求出其中大于、等于、小于它的数有多少。
3、这道题就OK了,具体看代码实现。
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<sstream>#include<algorithm>#include<vector>#include<bitset>#include<set>#include<queue>#include<stack>#include<map>#include<cstdlib>#include<cmath>#define PI 2*asin(1.0)#define LL long long#define pb push_back#define pa pair<int,int>#define clr(a,b) memset(a,b,sizeof(a))#define lson lr<<1,l,mid#define rson lr<<1|1,mid+1,r#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)#define key_value ch[ch[root][1]][0]C:\Program Files\Git\binconst int MOD = 1E9+7;const LL N = 2e5+15;const int maxn = 5e5+15;const int letter = 130;const int INF = 1e17;const double pi=acos(-1.0);const double eps=1e-10;using namespace std;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int w[N],n,m,q,ps[N],cnt;int c[2][N],ans[N][2];vector<int>G[N];vector<pa>que[N];void init(){ cnt=0; clr(c,0),clr(ans,0); for(int i=0;i<N;i++) G[i].clear(),que[i].clear();}int lowbit(int x) {return x&(-x);}void update(int i,int val,int f){ for(int x=i;x<=cnt;x+=lowbit(x)) c[f][x]+=val;}int getsum(int i,int f){ int ans=0; for(int x=i;x>0;x-=lowbit(x)) ans+=c[f][x]; return ans;}void dfs(int x){ for(int i=0;i<que[x].size();i++){ int id=que[x][i].first,pos=que[x][i].second; pos=lower_bound(ps+1,ps+cnt+1,pos)-ps; ///0 zuo 1you int lqb=getsum(cnt,0); int rqb=getsum(cnt,1); int lx=getsum(pos-1,0); ///xiaoyu int rx=getsum(pos-1,1); int ld=lqb-getsum(pos,0); int rd=rqb-getsum(pos,1); if(lx+ld+rx+rd!=lqb+rqb){ ans[id][0]=-1; continue; } ans[id][0]=rx; ans[id][1]=lx*3+rx*3+ld+rd; } for(int i=0;i<G[x].size();i++){ int vs=lower_bound(ps+1,ps+cnt+1,w[x])-ps; update(vs,1,i); dfs(G[x][i]); update(vs,-1,i); }}int main(){ int T; scanf("%d",&T); while(T--){ init(); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",w+i),ps[++cnt]=w[i]; scanf("%d",&m); for(int i=0;i<m;i++){ int u,a,b; scanf("%d%d%d",&u,&a,&b); G[u].pb(a),G[u].pb(b); } scanf("%d",&q); for(int i=1;i<=q;i++){ int id,x; scanf("%d%d",&id,&x); que[id].pb(make_pair(i,x)); ps[++cnt]=x; } sort(ps+1,ps+cnt+1); cnt=unique(ps+1,ps+cnt+1)-(ps+1); dfs(1); for(int i=1;i<=q;i++){ if(ans[i][0]==-1) puts("0"); else printf("%d %d\n",ans[i][0],ans[i][1]); } } return 0;}/**/
0 0
- hdu4605 Magic Ball Game(树状数组)
- hdu4605 Magic Ball Game
- HDU4605-Magic Ball Game
- HDU 4605 Magic Ball Game 树状数组
- HDU 4605 Magic Ball Game 树状数组
- Magic Ball Game - HDU 4605 树状数组
- HDU 4605 Magic Ball Game 树状数组
- hdu4605 Magic Ball Game,函数式线段树
- hdu 4605-Magic Ball Game(树状数组)
- hdu 4605 Magic Ball Game(离线+树状数组)
- hdu-4605 Magic Ball Game[离散化+回溯+树状数组]
- 树状数组+离线+hdu4605
- hdu4605Magic Ball Game 树状数组
- HDU 4605 Magic Ball Game(可持续化线段树,树状数组,离散化)
- 4605 Magic Ball Game
- hdu4605 树状数组+离散化+dfs
- hdu 4605 Magic Ball Game
- hdu 4605 Magic Ball Game
- html and css-task1
- java 读取 Excel文件
- php实习tips(正则表达式)
- 基本排序(包括插入,选择,冒泡排序)
- CodeChef PRIMEDSTPrime Distance On Tree
- hdu4605 Magic Ball Game(树状数组)
- Linux LVS+Keepalived负载均衡安装配置笔记
- PAT-B 1041. 考试座位号
- 软件工程(二)
- KMP算法
- WindowManager之凌驾所有Activity之上(自定义各种组件)
- MyTask3
- ArchLinux 安装 MongoDB
- EventBus的使用,注意事项,错误分析