2013 多校第一场 hdu 4605 Magic Ball Game
来源:互联网 发布:怎么出售淘宝店铺 编辑:程序博客网 时间:2024/05/17 04:27
hdu 4605
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4605
题目大意:给你一棵二叉树,每个节点有一个w值,现在有一颗小球,值为x,从根节点往下掉,如果w==x,那么它就会停止;如果w>x,那么它往左、右儿子的概率都是1、2;如果w<x,那么它往左儿子的概率是1/8,右儿子是7/8。现在给你q个询问,问你值为x的球道达节点u的概率为多少。
思路:比赛的时候,我们都是跟着榜走的,都卡在那道Deque上了,根本没有看这题。昨天晚上自己看了一下,其实也没有什么正确的解题思路,暴力谁都会,但是肯定超时,要不然也不会比赛时没几个队伍去做这题了。然后,当然就看题解了喽,看题解先开始就是有一个地方一直不明白,它所说的树状数组(线段树)到底维护的是什么,它的区间又是什么东西。想来想去一直没想明白,去网上看别人的博客,东看西看又找了个同学去问,感觉也还是这几个地方不懂(当然不是他们讲的不好,而是我有个地方卡壳了,对线段树这个工具应用还不熟啊),后来,自己按照他们讲的方向去想了想,终于顿悟了。它不是每次询问都输出,而是先把所有的询问都存起来,遍历的时候一次性弄完,再输出,这个不是重点,关键还是在我上面所说的树状数组那里,对于树状数组来说,每个叶子节点A[ i ]存的是当前dfs 走过的路径上 w为 i 的结点个数,这样dfs下来的时候,每次都做update操作(递归时A[ w ]+1,回溯时再减掉),当当前节点被mark时,就询问。关于x、y的计算方法是这样的:设a为从根节点到当前节点左路径中小于x的节点数,b为从根节点到当前节点左路径中大于x的节点数,c为右路径中小于的,d为右路径中大于的,则 x = c,y = b+d+3*(a +c),这个自己画个图想想,列列式子就明白了。由于dfs到某个节点,对应的树状数组里存的就是这条路径对应的个数,询问的复杂度是O(logn)。多以整个过程在一遍dfs过后就完成了。由于分左、右路径,所以我就开了两个树状数组,一个表示左,一个表示右,那些开一个的其实也一样,都要分左、右的。
话说,这道题之前我只会线段树,树状数组不会,虽然说是一直都想学来着。。 = = ,因为这道题,网上大家写的都是树状数组,我也想看看树状数组到底是什么东西,就去学了。结果发现,这东西果然简单,学学就是5分钟的事情,然后再顺便A道题目。。 它能实现一些简单的求和和更新操作,虽然适用范围比线段树小,但是人家编程复杂度小啊,敲起来快,简单,空间也省。因为这道题只需要求和和单点更新,果断是树状数组啊!
今天早上来了,果断把它A了,可是我这个代码我发现一个神奇的问题,如果我在dfs中处理mark节点时如果sum(x),sum(x-1)这些值先算好保存下来(免得重复算么)再算要求的值,就是RE(爆栈),而直接当场就算,就是AC的。。 神奇啊,不解。。 = =
代码如下:
#include<cstdio>#include<cstring>#include<map>#include<vector>#include<algorithm>using namespace std;#define MP make_pairconst int MAXN = 111111 ;struct Node{ int w,lson,rson;} node[MAXN];int mark[MAXN];vector < pair <int,int> > ques[MAXN];int ans[MAXN][2];int tot;int sum_l[MAXN],sum_r[MAXN];map <int,int> my_map;int lowbit(int x){ return x&(-x);}void update_left(int pos,int x){ while(pos<=tot) { sum_l[pos]+=x; pos += lowbit(pos); }}void update_right(int pos,int x){ while(pos<=tot) { sum_r[pos]+=x; pos += lowbit(pos); }}int sum_left(int pos){ int s=0; while(pos>=1) { s += sum_l[pos]; pos -= lowbit(pos); } return s;}int sum_right(int pos){ int s=0; while(pos>=1) { s += sum_r[pos]; pos -= lowbit(pos); } return s;}void dfs(int root){ if(root==-1) return ; if(mark[root]) { for(int i = 0;i<ques[root].size();i++) { int x = my_map[ques[root][i].first]; int id = ques[root][i].second; if(sum_left(x)-sum_left(x-1)>0||sum_right(x)-sum_right(x-1)>0) ans[id][0] = -1; else { ans[id][0] = sum_right(x-1); ans[id][1] = sum_left(tot)-sum_left(x)+sum_right(tot)-sum_right(x)+3*(sum_left(x-1)+sum_right(x-1)); } } } update_left(my_map[node[root].w],1); dfs(node[root].lson); update_left(my_map[node[root].w],-1); update_right(my_map[node[root].w],1); dfs(node[root].rson); update_right(my_map[node[root].w],-1);}void init(){ memset(sum_l,0,sizeof(sum_l)); memset(sum_r,0,sizeof(sum_r));}int hash[MAXN];int main(){ int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&node[i].w); hash[i] = node[i].w; } int m; scanf("%d",&m); int a,b,c; for(int i =1;i<=n;i++) node[i].lson = node[i].rson = -1; while(m--) { scanf("%d%d%d",&a,&b,&c); node[a].lson = b; node[a].rson = c; } int q; scanf("%d",&q); memset(mark,0,sizeof(mark)); for(int i = 1;i<=n;i++) ques[i].clear(); int u,x; for(int i = 1;i<=q;i++) { scanf("%d%d",&u,&x); mark[u] =1; ques[u].push_back(MP(x,i)); hash[n+i] = x; } sort(hash+1,hash+1+n+q); tot = unique(hash+1,hash+1+n+q)-hash-1; //printf("tot = %d\n",tot); my_map.clear(); for(int i=1;i<=tot;i++) my_map[hash[i]] = i; init(); 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;}
- 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
- HDU.4605 Magic Ball Game
- 2013 多校联合 F Magic Ball Game (hdu 4605)
- HDU 4605 Magic Ball Game 解题报告
- HDU 4605 Magic Ball Game 树状数组
- HDU 4605 Magic Ball Game 树状数组
- Magic Ball Game - HDU 4605 树状数组
- HDU 4605 Magic Ball Game 树状数组
- 4605 Magic Ball Game
- hdu 4605-Magic Ball Game(树状数组)
- hdu-4605-Magic Ball Game-线段树+离线操作
- hdu 4605 Magic Ball Game(离线+树状数组)
- PCI协议简析
- Yale CAS + .net Client 实现 SSO(3)--实现 ASP.NET WebForm Client
- 关于android里的修改权限读取framebuffer的open错误
- 黑马程序员-多线程(上)
- linux开启图形界面
- 2013 多校第一场 hdu 4605 Magic Ball Game
- 黑马程序员----2、java控制语句
- OK6410之TFTP/NFS环境配置,NFS文件系统启动注意事项
- Win7 64bit系统下未能加载文件或程序集“System.Data.SQLite”的解决办法
- Yale CAS + .net Client 实现 SSO(4)--实现基于数据库的身份验证
- 设计模式的UML图
- [项目心得]自己的第一个项目1
- Yale CAS + .net Client 实现 SSO(5)--扩展基于数据库的身份验证
- Android OneDayOneExample-2. 读取电话本