码迷,mamicode.com
首页 > 其他好文 > 详细

数列找不同

时间:2019-07-24 00:36:48      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:namespace   set   一个   printf   etc   sub   getc   离线   amp   

题目描述

现有数列A_1,A_2,\cdots,A_NA1?,A2?,?,AN?,Q 个询问(L_i,R_i)(Li?,Ri?),A_{Li} ,A_{Li+1},\cdots,A_{Ri}ALi?,ALi+1?,?,ARi? 是否互不相同

输入格式

第1 行,2 个整数N,QN,Q

第2 行,N 个整数A_{Li} ,A_{Li+1},\cdots,A_{Ri}ALi?,ALi+1?,?,ARi?

Q 行,每行2 个整数L_i,R_iLi?,Ri?

输出格式

对每个询问输出一行,“Yes” 或者“No”

输入输出样例

输入 #1
4 2
1 2 3 2
1 3
2 4
输出 #1
Yes
No

说明/提示

• 对于50% 的数据,N,Q \le 10^3N,Q103

• 对于100% 的数据,1 \le N,Q \le 10^5, 1 \le A_i \le N, 1 \le L_i \le R_i \le N1N,Q105,1Ai?N,1Li?Ri?N

 

 

我们想,因为每次查询是离线的,所以我们先给每次的查询排一个序。

排序的方法是

分块。

我们把所有的元素分成多个块(即分块)。分了块跑的会更快。再按照右端点从小到大,左端点块编号相同按右端点从小到大。

 

#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;

const int maxn=100010;

inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<0||ch>9){
        if(ch==-){
            w=-1;
        }
        ch=getchar();
    }
    while(ch>=0&&ch<=9){
        s=s*10+ch-0;
        ch=getchar();
    }
    return s*w;
}

int n,m,hhh,ans=0,kkksc03,kkksc04,cnt[maxn],a[maxn],i;

bool anb[maxn];

struct node{
    int l,r,p;
}q[maxn];

bool cmp(const node x,const node y){
    return (x.l/hhh)==(y.l/hhh)?x.r<y.r:x.l<y.l;
}

void add(int position){
    if((++cnt[a[position]])==1){
        ++ans;
    }
}

void remove(int position){
    if((--cnt[a[position]])==0){
        --ans;
    }
}

int main(){
    n=read();
    m=read();
    hhh=sqrt(n);
    for(i=1;i<=n;i++){
        a[i]=read();
    }
    for(i=1;i<=m;i++){
        q[i].l=read();
        q[i].r=read();
        q[i].p=i;
    }
    sort(q+1,q+1+m,cmp);
    for(i=1;i<=m;i++){
        int L=q[i].l,R=q[i].r;
        while(kkksc03<L){
            remove(kkksc03++);
        }
        while(kkksc03>L){
            add(--kkksc03);
        }
        while(kkksc04<R){
            add(++kkksc04);
        }
        while(kkksc04>R){
            remove(kkksc04--);
        }
        if(ans==(R-L+1)){
            anb[q[i].p]=1;
        }
    }
    for(i=1;i<=m;i++){
        if(anb[i]==1){
            printf("Yes\n");
        }
        else{
            printf("No\n");
        }
    }
    return 0;
}

 

数列找不同

标签:namespace   set   一个   printf   etc   sub   getc   离线   amp   

原文地址:https://www.cnblogs.com/hrj1/p/11235037.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!