莫队+数组低级化的 优先队列

题目:

view
3s 512M

【题目表述】

某天醒来,koishi发现自己变成了一支彩笔。并且他站在一排彩笔之中。

一开始每支彩笔的彩笔程度都为1。如果有两支彩笔颜色相同,那么他们就能合二为一,并且彩笔程度相加。

现在koishi想知道,从第l支彩笔到第r支彩笔,最多能有多大的彩笔程度。

【输入格式】

第一行为彩笔数量n和询问次数q
第二行为n个这个整数,每个整数代表这个彩笔的颜色
接下来q行,每行两个整数l和r

【输出格式】
共q行,每行一个整数,表示最大的彩笔程度

【样例输入】
6 2
1 3 2 3 3 2
1 6
2 4

【样例输出】
3
2

【数据范围与提示】
1<=n,q<=3*1e5
1<=彩笔颜色<=n
1<=l<=r<=n

对于样例的第一个询问,颜色为1的彩笔程度为1,颜色为2的彩笔程度为2,3的彩笔程度为3,因此彩笔程度最大为3。
对于第二个询问,颜色为2的彩笔程度为1,颜色为3的彩笔程度为2,因此彩笔程度最大为2。

代码:

#include <bits/stdc++.h>
using namespace std;
#define M 300010
#define ri register int

template <class G>void read(G &x)
{
    x=0;int f=0;char ch=getchar();
    while(ch<'0'||ch>'9'){f|=(ch=='-');ch=getchar();}
    while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x=f?-x:x;
    return;
}

struct dian {
    int l,r,pos,id;
    bool operator <(const dian &t)const 
    {
        if(pos==t.pos&&r==t.r) return l<t.l;
        if(pos==t.pos) return r<t.r;
        return pos<t.pos;
    }
}p[M];

int val[M];

int n,m;
int mx,cur;
int num[M],cc[M];

struct cmp{
    bool operator ()(const int a,const int b)const 
    {
        return num[a]<num[b];
    }
};
priority_queue<int,vector<int>,cmp> q;

void work(int a,int b)
{
    cc[num[val[a]]]--;
    num[val[a]]+=b;
    cc[num[val[a]]]++;
    if(mx<num[val[a]]) mx=num[val[a]];
    if(cc[mx]==0) mx--;
}

int ans[M];
void solvee()
{
     
    sort(p+1,p+1+m);
    
    int l=1,r=0; // ATTENTION
    
    for(ri i=1;i<=m;i++)
    {
        while(l<p[i].l) work(l++,-1);
        while(l>p[i].l) work(--l,1);
        while(r<p[i].r) work(++r,1);
        while(r>p[i].r) work(r--,-1);
        ans[p[i].id]=mx;
    }

}
int main(){
    
    freopen("D:\\学习\\C++\\swjtu比赛\\2021校赛决赛文档\\彩笔程度\\data\\asmall_lb_ri_4.in","r",stdin);
    read(n);read(m);
    
    for(ri i=1;i<=n;i++)
    read(val[i]);
    
    int k=int(sqrt(n)+0.5);
    for(ri i=1;i<=m;i++)
    {
        read(p[i].l);
        read(p[i].r);
        p[i].pos=p[i].l/k;
        p[i].id=i;
    }
    
    solvee();
    
    for(ri i=1;i<=m;i++)
    printf("%d\n",ans[i]);
    
} 
View Code

 

思维: 1 在用一个数组来表示 每一个数量有多少个数量,哈哈哈哈 喵喵喵

            2 优先队列,不适用 ,去死吧

posted @ 2021-11-30 20:26  VxiaohuanV  阅读(28)  评论(0编辑  收藏  举报