程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU-4973-A simple simulation problem.(二分+樹狀數組)

HDU-4973-A simple simulation problem.(二分+樹狀數組)

編輯:C++入門知識

HDU-4973-A simple simulation problem.(二分+樹狀數組)


Problem Description There are n types of cells in the lab, numbered from 1 to n. These cells are put in a queue, the i-th cell belongs to type i. Each time I can use mitogen to double the cells in the interval [l, r]. For instance, the original queue is {1 2 3 3 4 5}, after using a mitogen in the interval [2, 5] the queue will be {1 2 2 3 3 3 3 4 4 5}. After some operations this queue could become very long, and I can’t figure out maximum count of cells of same type. Could you help me?
Input The first line contains a single integer t (1 <= t <= 20), the number of test cases.

For each case, the first line contains 2 integers (1 <= n,m<= 50000) indicating the number of cell types and the number of operations.

For the following m lines, each line represents an operation. There are only two kinds of operations: Q and D. And the format is:

“Q l r”, query the maximum number of cells of same type in the interval [l, r];
“D l r”, double the cells in the interval [l, r];

(0 <= r – l <= 10^8, 1 <= l, r <= the number of all the cells)
Output For each case, output the case number as shown. Then for each query "Q l r", print the maximum number of cells of same type in the interval [l, r].

Take the sample output for more details.

Sample Input
1
5 5
D 5 5
Q 5 6
D 2 3
D 1 2
Q 1 7

Sample Output
Case #1:
2
3

Source 2014 Multi-University Training Contest 10
思路:找位置的時候直接二分查找。兩個數組分別保存區間和、單點計數。
#include 
#define max(A,B)(A>B?A:B)

long long node[50005],cnt[50005];
int n,m;

long long sum(int x)
{
    long long res=0;

    while(x>=1)
    {
        res+=node[x];
        x-=x&-x;
    }

    return res;
}

void add(int x,long long val)
{
    while(x<=n)
    {
        node[x]+=val;
        x+=x&-x;
    }
}

int getpos(long long val)
{
    int l=1,r=n,mid,res;

    while(l<=r)
    {
        mid=(l+r)>>1;

        if(sum(mid)>=val)
        {
            res=mid;

            r=mid-1;
        }
        else l=mid+1;
    }

    return res;
}

int main()
{
    int T,i,l,r,cases=1;
    long long a,b,tempa,tempb,ans;
    char s[5];

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d%d",&n,&m);

        printf("Case #%d:\n",cases++);

        for(i=1;i<=n;i++) node[i]=0,cnt[i]=1;

        for(i=1;i<=n;i++) add(i,1);

        while(m--)
        {
            scanf("%s%I64d%I64d",s,&a,&b);

            if(s[0]=='D')
            {
                l=getpos(a);
                r=getpos(b);

                if(l==r)
                {
                    cnt[l]+=b-a+1;
                    add(l,b-a+1);
                }
                else
                {
                    tempa=sum(l)-a+1;
                    tempb=b-sum(r-1);

                    cnt[l]+=tempa;
                    add(l,tempa);

                    cnt[r]+=tempb;
                    add(r,tempb);

                    for(i=l+1;i<=r-1;i++)
                    {
                        add(i,cnt[i]);
                        cnt[i]+=cnt[i];
                    }
                }
            }
            else
            {
                l=getpos(a);
                r=getpos(b);

                if(l==r) printf("%I64d\n",b-a+1);
                else
                {
                    ans=max(sum(l)-a+1,b-sum(r-1));

                    for(i=l+1;i<=r-1;i++) ans=max(ans,cnt[i]);

                    printf("%I64d\n",ans);
                }
            }
        }
    }
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved