Luo Gu P3901 series to find different (MO team resolved)

Topic links : https://www.luogu.com.cn/problem/P3901
Here Insert Picture Description
MO team resolved :
the essence :
by asking a reasonable sort, then superior order violence to answer every inquiry.
After processing a query, can use its information to the next query section help
thinking sort :
a minimum distance of every two intervals
A method of sorting :
original sequence (of length n), to be the root of a number n block .
The first sort key is interrogation number where the left end of the block , the second key is the interrogation position of the right end of itself , is ascending .
Then "move left and right for the current segment endpoint" method, according to the order of evaluation of each answer interrogation interval, each mobile terminal can be determined interrogation zone around the next interval answer.
For example: in the interval [1,5], based on the 1 position is removed (ie, the left end of the right one), plus 6 answer position (ie, a right end of the right), to give the interval [2,6] of.
Code :

#include<cstdio>
#include<cstring>
#include<math.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int n,q;
int pos[N],a[N],book[N];
int sum;
struct node
{
    int l,r,id;
    int ans;
} val[N];
int cmp(node t1,node t2)
{
    if(pos[t1.l]==pos[t2.l])
        return t1.r<t2.r;
    return pos[t1.l]<pos[t2.l];
}
int cmp1(node t1,node t2)
{
    return t1.id<t2.id;
}
void update(int o,int k)
{
    if(k==1)
    {
        book[a[o]]++;
        if(book[a[o]]==1)
            sum++;
    }
    else
    {
        if(book[a[o]]==1)
            sum--;
        book[a[o]]--;
    }
}
void init()
{
    sum=0;
    memset(book,0,sizeof(book));
    memset(pos,0,sizeof(pos));
}
int main()
{
    init();
    scanf("%d%d",&n,&q);
    int b=sqrt(n);/*块的大小*/
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        pos[i]=i/b;
    }
    for(int i=1; i<=q; i++)
    {
        scanf("%d%d",&val[i].l,&val[i].r);
        val[i].id=i;/*还原起初的询问顺序*/
    }
    sort(val+1,val+1+q,cmp);
    int l=1,r=0;/*相当于两个指针,对指针进行相应变换,指向给定区间*/
    for(int i=1; i<=q; i++)
    {
        while(l<val[i].l)
            update(l++,-1);
        while(l>val[i].l)
            update(--l,1);
        while(r>val[i].r)
            update(r--,-1);
        while(r<val[i].r)
            update(++r,1);
        if(sum==(val[i].r-val[i].l+1))
            val[i].ans=1;
        else
            val[i].ans=0;
    }
    sort(val+1,val+1+q,cmp1);
    for(int i=1; i<=q; i++)
    {
        if(val[i].ans==1)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}
Published 165 original articles · won praise 6 · views 4996

Guess you like

Origin blog.csdn.net/lylzsx20172018/article/details/104102770