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 <stdio.h>
#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);
                }
            }
        }
    }
}
时间: 2024-12-23 23:28:56

HDU-4973-A simple simulation problem.(二分+树状数组)的相关文章

hdu 4973 A simple simulation problem.(线段树)

http://acm.hdu.edu.cn/showproblem.php?pid=4973 有两种操作 D l r 将[l,r]区间翻倍 Q l r询问[l,r]中相同数字出现的最多次数 比赛的时候脑子太乱了,没有想到怎么做.发现每次翻倍序列的长度都在变化,区间对应的数也在变,没有思路. 但是静下心来想一想,思路还是挺清晰的. 无论怎么翻倍,序列中的数都是连续的,范围是1~n.可以拿一个数组来记录每个数出现的次数,当更新或询问区间[l,r]时,可以利用其前缀和找到区间[l,r]对应的数字分别是

hdu - 4973 - A simple simulation problem.(线段树单点更新 + 区间更新)

题意:初始序列 1, 2, ..., n,m次操作(1 <= n,m<= 50000),每次操作可为: D l r,将区间[l, r]中的所有数复制一次: Q l r,输出区间[l, r]中同一数字个数的最大值. (0 <= r – l <= 10^8, 1 <= l, r <= 序列元素个数) 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4973 -->>因为区间内数字是依次递增的,所以可以以数字为叶建线段

HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences                                  Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                             

HDU 4417 类似求逆序数的树状数组

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2250    Accepted Submission(s): 1092 Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability

CF #261 div2 D. Pashmak and Parmida&amp;#39;s problem (树状数组版)

Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants her partner to be clever too (although he's not)! Parmida has prepared the following test problem for Pashmak. There is a sequence a that consists of n

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida&#39;s problem (树状数组求逆序数 变形)

题目链接 题意: 给出一些数a[n],求(i, j), i<j 的数量,使得:f(1, i, a[i]) > f(j, n, a[j]) . f(lhs, rhs, x) 指在 { [lhs, rhs]范围中,a[k]的值=x } 的数量. 1.  f(1, i, a[i]) 就是指a[i]前面包括a[i]的数中,有几个值=a[i]. 2.  f(j, n, a[j]) 就是指a[j]后面包括a[j]的数中有几个值=a[j]. 虽然a[x]范围不小,但是n的范围是1000,不是很大,所以我们可

11525 - Permutation(二分+树状数组)

题目链接:点击打开链接 题意:从1~k的所有排列中找到第n个排列, n由公式给出. 思路:可以发现, 这个公式就是康托展开公式(康托展开百科:点击打开链接). 那么s[i]的意思就是i个数中当前数排在第几. 如此, 可以用二分+树状数组快速求解, 和一道BC题目神似. 细节参见代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<st

Codeforces 374D Inna and Sequence 二分+树状数组

题目链接:点击打开链接 给定n个操作,m长的序列a 下面n个数 if(co>=0)则向字符串添加一个co (开始是空字符串) else 删除字符串中有a的下标的字符 直接在序列上搞,简单模拟 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h&

【bzoj2527】[Poi2011]Meteors 整体二分+树状数组

题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BIU的第i个成员国希望能够收集Pi单位的陨石样本.你的任务是判断对于每个国家,它需要在第几次陨石雨之后,才能收集足够的陨石. 输入 第一行是两个数N,M. 第二行有M个数,第i个数Oi表示第i段轨道上有第Oi个国家的太空站. 第三行有N个数,第i个数Pi表示第i个国家希望收集的陨石数量. 第四行有一个