[bzoj 4241] historical research

Professor JOI, the first person to study the history of IOI, recently obtained a diary written by the residents of ancient IOI. In order to study the life of ancient IOI through this diary, Professor JOI began to investigate the events recorded in the diary.
The diary records the time of N consecutive days, about one occurrence per day.
There are different kinds of events. The type of event on day i (1 < = i < = n) is represented by an integer Xi. The larger Xi is, the larger the event size is.
Professor JOI decided to analyze these diaries in the following ways:
1. Select consecutive days in the journal as the time period for analysis
2. The importance of event type T is t * (the number of events with importance of T in this period)
3. Calculate the importance of all kinds of events, and output the maximum value. Now you are required to make a program to help teach the analysis. Each time you give the analysis range, you need to output the maximum value of the importance.

This problem is easy to add with Mo team, but difficult to delete, so we use a thing called roll back Mo team.
We define l as the left endpoint of the next block of the block where the left endpoint of the current query is located, and r as the right endpoint of the block where the left endpoint of the current query is located (at the beginning). After sorting, if the left endpoint of the query is the same block, the right endpoint of their query will increase.
Then we can increase r monotonically. If we record the answer as s2, l will change to the left end of the query, record the final answer as s1, and then l will move back to the original position to the right to eliminate the influence of L to the left, s1=s2. Then the problem will be solved.

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
inline long long Max(long long a,long long b){return a>b?a:b;}
struct node
{
    int l,r,id;
    long long s;
    node(){l=s=0;}
}q[100010],b[100010];
int n,m,cnt; 
int a[100010],belong[100010],ex[100010];
long long s1,s2,sum[100010],num[100010];
void fk()
{
    cnt=sqrt(n);
    for(int i=1;i<=n;i++)belong[i]=(i-1)/cnt+1;
}
bool cmp1(node a,node b)
{
    if(belong[a.l]==belong[b.l])
    {
        if(a.r>b.r)return false;
        if(a.r<b.r)return true;
        return 0;
    }
    if(belong[a.l]>belong[b.l])return false;
    if(belong[a.l]<belong[b.l])return true;
}
bool cmp2(node a,node b)
{
    if(a.id>b.id)return false;
    if(a.id<b.id)return true;
    return 0;
}
bool cmp3(node a,node b)
{
    if(a.s>b.s)return false;
    if(a.s<b.s)return true;
    return 0;
}
void add(int x)
{
    sum[x]+=ex[x];
    s1=Max(s1,sum[x]);
}
int main()
{
    int ss=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&b[i].s),b[i].id=i;
    sort(b+1,b+n+1,cmp3);
    for(int i=1;i<=n;i++)
    {
        if(b[i].s!=b[i-1].s)ss++;
        a[b[i].id]=ss;
        ex[ss]=b[i].s;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&q[i].l,&q[i].r);q[i].id=i;
    }
    fk();
    sort(q+1,q+m+1,cmp1);
    int l,r;
    for(int i=1;i<=m;i++)
    {
        if(belong[q[i].l]!=belong[q[i-1].l])
        {
            memset(sum,0,sizeof(sum));
            s1=s2=0;
            l=belong[q[i].l]*cnt+1;r=l-1;
        }
        if(belong[q[i].l]==belong[q[i].r])
        {
            long long ans=0;      
            for(int j=q[i].l;j<=q[i].r;j++)
            {
                num[a[j]]+=ex[a[j]];ans=Max(ans,num[a[j]]);
            }
            q[i].s=ans;
            for(int j=q[i].l;j<=q[i].r;j++)num[a[j]]-=ex[a[j]];
        }
        else
        {
            for(int j=r+1;j<=q[i].r;j++)add(a[j]);
            s2=s1;
            for(int j=l-1;j>=q[i].l;j--)add(a[j]);
            q[i].s=s1;
            for(int j=q[i].l;j<=l-1;j++)sum[a[j]]-=ex[a[j]];
            s1=s2;
            r=q[i].r;
        }
    }
    sort(q+1,q+m+1,cmp2);
    for(int i=1;i<=m;i++)printf("%lld\n",q[i].s);
    return 0;
}

Posted by kitegirl on Sun, 05 Apr 2020 21:58:44 -0700