求数组越界SP32900 (莫队)
  • 板块学术版
  • 楼主T20201126
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/9/8 20:29
  • 上次更新2023/10/27 12:15:38
查看原帖
求数组越界SP32900 (莫队)
419474
T20201126楼主2022/9/8 20:29

PS:PS:大于n的对答案没有贡献,所以没考虑

题面翻译

【题目大意】

你有一个长度为 nn 的数列 aa ,有 qq 次询问,每次询问给出三个整数:llrrkk。询问若区间 [l,r][l,r] 的众数的出现次数为 ss,比较 s×ks\times krl+1r - l + 1 的大小,如果前者大于等于后者,那么输出 YES,否则输出NO

【数据范围】

0<n,q2×1050 < n,q \le 2\times 10^50<k5×1050< \sum k \le 5\times 10^50<l,rn0<l,r\le n

保证输入的所有数字在 int 范围内


#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=600005;

ll n,m,l,r,a[N],pos[N],ans[N],num1[N],num2[N],cnt,res;

struct node{
    ll l,r,k,ID;
    inline bool operator < (const node &b)const{
        if(pos[l]!=pos[b.l]) return l<b.l;
        if(pos[l]&1) return r<b.r;
            else return r>b.r;
    }
}xu[N];
inline ll read()
{
    ll x=0;int b=1;char c=getchar();
    while(!isdigit(c)){
        if(c=='-') b=-1;
        c=getchar();
    }
    while(isdigit(c)){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*b;
}
void add(ll w)
{
    ++num1[a[w]];
    --num2[num1[a[w]]-1];
    ++num2[num1[a[w]]];
    res=max(res,num1[a[w]]);
    return ;
}
void sub(ll w)
{
    --num1[a[w]];
    ++num2[num1[a[w]]];
    --num2[num1[a[w]]+1];
    if(num2[res]==0)
        res--;
    return ;
}
int main()
{
    n=read();m=read();cnt=sqrt(n);
    for(int i=1;i<=n;++i){
        a[i]=read();
        pos[i]=(i-1)/cnt+1;
    }
    for(int i=1;i<=m;++i)
    {
        xu[i].l=read(); xu[i].r=read();
        xu[i].k=read(); xu[i].ID=i;
    }
    sort(xu+1,xu+1+m);
    l=1;r=0;res=0;
    for(int i=1;i<=m;++i)
    {
        while(xu[i].l<l) add(--l);
        while(xu[i].r>r) add(++r);
        while(xu[i].l>l) sub(l++);
        while(xu[i].r<r) sub(r--);
        ans[xu[i].ID]=(res*xu[i].k>=xu[i].r-xu[i].l+1);
    }
    for(int i=1;i<=m;++i)
        ans[i]==1?printf("YES\n"):printf("NO\n");
    return 0;
 } 
2022/9/8 20:29
加载中...