• hdu4605 树状数组+离散化+dfs


    Magic Ball Game

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 2189    Accepted Submission(s): 634

    Problem Description
    When the magic ball game turns up, Kimi immediately falls in it. The interesting game is made up of N balls, each with a weight of w[i]. These N balls form a rooted tree, with the 1st ball as the root. Any ball in the game has either 0 or 2 children ball. If a node has 2 children balls, we may define one as the left child and the other as the right child.
    The rules are simple: when Kimi decides to drop a magic ball with a weight of X, the ball goes down through the tree from the root. When the magic ball arrives at a node in the tree, there's a possibility to be catched and stop rolling, or continue to roll down left or right. The game ends when the ball stops, and the final score of the game depends on the node at which it stops.
    After a long-time playing, Kimi now find out the key of the game. When the magic ball arrives at node u weighting w[u], it follows the laws below:
    1  If X=w[u] or node u has no children balls, the magic ball stops.
    2  If X<w[u], there's a possibility of 1/2 for the magic ball to roll down either left or right.
    3  If X>w[u], the magic ball will roll down to its left child in a possibility of 1/8, while the possibility of rolling down right is 7/8.
    In order to choose the right magic ball and achieve the goal, Kimi wonders what's the possibility for a magic ball with a weight of X to go past node v. No matter how the magic ball rolls down, it counts if node v exists on the path that the magic ball goes along.
    Manual calculating is fun, but programmers have their ways to reach the answer. Now given the tree in the game and all Kimi's queries, you're required to answer the possibility he wonders.
     
    Input
    The input contains several test cases. An integer T(T≤15) will exist in the first line of input, indicating the number of test cases.
    Each test case begins with an integer N(1≤N≤105), indicating the number of nodes in the tree. The following line contains N integers w[i], indicating the weight of each node in the tree. (1 ≤ i ≤ N, 1 ≤ w[i] ≤ 109, N is odd)
    The following line contains the number of relationships M. The next M lines, each with three integers u,a and b(1≤u,a,b≤N), denotes that node a and b are respectively the left child and right child of node u. You may assume the tree contains exactly N nodes and (N-1) edges.
    The next line gives the number of queries Q(1≤Q≤105). The following Q lines, each with two integers v and X(1≤v≤N,1≤X≤109), describe all the queries.
     
    Output
    If the magic ball is impossible to arrive at node v, output a single 0. Otherwise, you may easily find that the answer will be in the format of 7x/2y . You're only required to output the x and y for each query, separated by a blank. Each answer should be put down in one line.
     
    Sample Input
    1 3 2 3 1 1 1 2 3 3 3 2 1 1 3 4
     
    Sample Output
    0 0 0 1 3
     
    Source
    /*
    hdu4605 树状数组+离散化+dfs
    一个很明显的错误,在网上找了几个测试案例居然都过了TAT,也是无语
    最开始发现可以通过判断你走到当前节点左右的次数 和 比你小的个数
    
    比X大 1/2 1/2    比X小 1/8 7/8
    相当于比X大时有一个2,当比X小时有3个2   7则看情况。
    所以可以遍历树,然后判断。   比当前数小的数的个数则用树状数组维护
    
    但是最开始写出来翻了很2的错误,我只保存了到当前节点小的数个数
    (即没有区分左右)以及左右次数,但实际上这样并不能得出有多少次在比它小
    的时候往右走即7/8的次数
    
    于是乎把树状数组保存的内容弄成二维的就好了。然后就是最开始的离散化了
    hhh-2016-03-03 22:57:09
    */
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <iostream>
    #include <cstring>
    #include <map>
    #include <cstdio>
    #include <vector>
    #include <functional>
    using namespace std;
    typedef long long ll;
    const int maxn = 150050;
    const int inf = 0x3f3f3f3f;
    int s[maxn*2][2];
    int n,tot;
    int ans[maxn][2];
    int vec[maxn*2];
    int vis[maxn];
    struct node
    {
        int val;
        int l,r;
    } pnode[maxn];
    
    
    vector<pair<int,int> >qu[maxn];
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    void add(int x,int val,int i)
    {
        while(x <= tot)
        {
            s[x][i]+=val;
            x += lowbit(x);
        }
    }
    
    int sum(int x,int i)
    {
        int cnt = 0;
        while(x)
        {
            cnt += s[x][i];
            x -= lowbit(x);
        }
        return cnt;
    }
    
    void dfs(int u,int l,int r)
    {
        int lson=pnode[u].l,rson=pnode[u].r,pos;
        for(int i = 0; i < (int)qu[u].size(); i++)
        {
            int id = qu[u][i].first;
            int lim = qu[u][i].second;
            pos = lower_bound(vec,vec+tot,lim)-vec+1;
            int ls = sum(pos-1,0);
            int rs = sum(pos-1,1);
            int lls = sum(pos,0);
            int rrs = sum(pos,1);
            if(ls+rs != lls+rrs)
            {
                ans[id][0] = -1;
                continue;
            }
            ans[id][0] = (ls+rs)*2+l+r;
            ans[id][1] = rs;
        }
        pos = lower_bound(vec,vec+tot,pnode[u].val)-vec+1;
    
        if(lson != -1)
        {
            add(pos,1,0);
            dfs(lson,l+1,r);
            add(pos,-1,0);
        }
        if(rson != -1)
        {
            add(pos,1,1);
            dfs(rson,l,r+1);
            add(pos,-1,1);
        }
        return ;
    }
    
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(s,0,sizeof(s));
            memset(ans,0,sizeof(ans));
            int m,q,M,v;
            tot = 0;
            scanf("%d",&n);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d",&pnode[i].val);
                pnode[i].l = pnode[i].r = -1;
                vec[tot++] = (pnode[i].val);
            }
            scanf("%d",&m);
            for(int i =1; i <= m; i++)
            {
                int x;
                scanf("%d",&x);
                scanf("%d%d",&pnode[x].l,&pnode[x].r);
            }
            scanf("%d",&q);
            for(int i =1; i <= q+n; i++)qu[i].clear();
            for(int i =1; i <= q; i++)
            {
                scanf("%d%d",&v,&M);
                qu[v].push_back(make_pair(i,M));
                vec[tot++] = M;
            }
            sort(vec,vec+tot);
            tot = unique(vec,vec+tot)-vec;
            dfs(1,0,0);
            for(int i =1; i <=q ; i++)
            {
                if(ans[i][0] == -1)
                    printf("0
    ");
                else
                    printf("%d %d
    ",ans[i][1],ans[i][0]);
            }
        }
        return 0;
    }
    

      



  • 相关阅读:
    为App签名(为apk签名)
    Android如何获取网络连接状态(3G/Wifi)及怎样调用网络配置界面
    android textview改变部分文字的颜色和string.xml中文字的替换及部分内容设置颜色、字体、超链接、图片
    Toast和Looper。Handler消息循环机制
    android 创建DateTime类型的数据库
    Android中dp和px之间进行转换
    Java的ThreadPoolExecutor使用几点建议
    ListView中设置item点击状态的背景色
    android 让一个控件按钮居于底部的几种方法
    sqlite3数据类型和函数
  • 原文地址:https://www.cnblogs.com/Przz/p/5409607.html
Copyright © 2020-2023  润新知