1. 程式人生 > >Gym-101879 H 莫隊演算法

Gym-101879 H 莫隊演算法

先把溫度離散化

c[]代表這個溫度有幾個

sum[]代表有幾天同樣溫度的溫度個數

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=30005;
int t[N],b[N],c[N],sum[N],ANS;
struct node
{
    int l,r,id,ans;
}a[N];
int n,q,m,k;
bool cmp(node a,node b)
{
    if(a.l/k==b.l/k) return a.r<b.r;
    else return a.l<b.l;
}
bool cmp_id(node a,node b)
{
    return a.id<b.id;
}
void update(int x,int o)
{
    if(o==1)
    {
        c[x]++;
        sum[c[x]]++;
    }
    else
    {
        sum[c[x]]--;
        c[x]--;
    }
    while(sum[ANS+1]>=ANS+1) ANS++;
    while(sum[ANS]<ANS) ANS--;
}
int main()
{

    scanf("%d%d",&n,&q);
    k=sqrt(n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&t[i]);
        b[i]=t[i];
    }
    sort(b+1,b+1+n);
    m=unique(b+1,b+1+n)-b;
    for(int i=1;i<=n;i++)
        t[i]=lower_bound(b+1,b+m,t[i])-b;
	for(int i=0;i<q;i++)
    {
        scanf("%d%d",&a[i].l,&a[i].r);
        a[i].id=i;
    }
    for(int i=0;i<=m;i++)
        b[i]=0;
	sort(a,a+q,cmp);
	ANS=0;
	for(int i=0,l=1,r=0;i<q;i++)
    {
        for(;r<a[i].r;r++)
            update(t[r+1],1);
		for(;r>a[i].r;r--)
		    update(t[r],-1);
		for(;l<a[i].l;l++)
		    update(t[l],-1);
		for(;l>a[i].l;l--)
		    update(t[l-1],1);
        a[i].ans=ANS;
    }
    sort(a,a+q,cmp_id);
    for(int i=0;i<q;i++)
        printf("%d\n",a[i].ans);
	return 0;
}