• Luogu P3901 数列找不同 (莫队模版)


    传送门

    这是一个莫队板子qwq

    莫队是一种离线暴力算法,每次通过调整当前询问和上次询问的区间的不同的左右端点,并修改答案。

    可以看出,调整的越少跑得越快,所以每次先把询问的左右端点排个序,按左端点分块,块相同的按右端点排序

    (玄学)

    代码如下

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #define MogeKo qwq
    using namespace std;
    const int maxn = 1e5+10;
    int n,q,sum,siz;
    int a[maxn],num[maxn];
    bool ans[maxn];
    struct node {
        int id,l,r,block;
        bool operator < (const node & A)const {
            return block < A.block || (block == A.block && r < A.r);
        }
    } b[maxn];
    
    void add(int x) {
        if(!num[a[x]])sum++;
        num[a[x]]++;
    }
    
    void del(int x) {
        num[a[x]]--;
        if(!num[a[x]])sum--;
    }
    
    void Mo() {
        for(int i = b[1].l; i <= b[1].r; i++)
            add(i);
        if(sum == b[1].r-b[1].l+1)ans[b[1].id] = true;
        int L = b[1].l;
        int R = b[1].r;
        for(int i = 2; i <= q; i++) {
            while(L<b[i].l)del(L++);
            while(L>b[i].l)add(--L);
            while(R>b[i].r)del(R--);
            while(R<b[i].r)add(++R);
            if(sum == b[i].r-b[i].l+1)ans[b[i].id] = true;
        }
    }
    
    int main() {
        scanf("%d%d",&n,&q);
        int siz = sqrt(n);
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        for(int i = 1; i <= q; i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            b[i].id = i;
            b[i].l = x;
            b[i].r = y;
            b[i].block = x/siz;
        }
        sort(b+1,b+q+1);
        Mo();
        for(int i = 1; i <= q; i++)
            if(ans[i])printf("Yes
    ");
            else printf("No
    ");
        return 0;
    }
    View Code
  • 相关阅读:
    每天拿出来2小时浪费(文/王路) 作者: 王路
    objective-c自学总结(二)---init/set/get方法
    objective-c自学总结(一)---面向对象
    水仙花数
    独木舟上的旅行
    阶乘之和
    小明的调查统计
    管闲事的小明
    重温《STL源码剖析》笔记 第一章
    重温《STL源码剖析》笔记 第三章
  • 原文地址:https://www.cnblogs.com/mogeko/p/11253930.html
Copyright © 2020-2023  润新知