算法学习:莫队

【luogu P3901】数列找不同

【题意】给一整数序列,Q个询问,询问区间内数字是否互不相同

 

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #define ll long long 
 5 using namespace std;
 6 const int MAXN = 100010;
 7 ll a[MAXN],cnt[MAXN],ans[MAXN],c;
 8 int siz;
 9 struct node
10 {
11     int l, r, id;
12     bool operator<(node a)
13     {
14         if (((l - 1) / siz) == ((a.l - 1) / siz))
15             return r < a.r;
16         return l / siz < a.l / siz;
17     }
18 }mo[MAXN];
19 void add(int pos)
20 {
21     
22     cnt[pos]++;
23     if(cnt[pos]==1)
24         c++;
25 }
26 void del(int pos)
27 {
28     cnt[pos]--;
29     if(cnt[pos]==0)
30         c--;
31 }
32 int main()
33 {
34     int n, m, k;
35     scanf("%d%d", &n, &m);
36     siz = (int)sqrt(n);
37     for (int i = 1; i <= n; i++)
38     {
39         scanf("%d", &a[i]);
40     }
41     for (int i = 1; i <= m; i++)
42     {
43         scanf("%d%d", &mo[i].l, &mo[i].r);
44         mo[i].id = i;
45     }
46     sort(mo + 1, mo + 1 + m);
47     int ansl=1, ansr=0;
48     for (int i = 1; i <= m; i++)
49     {
50         int l = mo[i].l, r = mo[i].r;
51         while (ansl > l) ansl--, add(a[ansl]);
52         while (ansr < r) ansr++, add(a[ansr]);
53         while (ansl < l) del(a[ansl]), ansl++;
54         while (ansr > r) del(a[ansr]), ansr--;
55         ans[mo[i].id] = c==r-l+1;
56     }
57 
58     for (int i = 1; i <= m; i++)
59         printf("%s\n", ans[i]?"Yes":"No");
60 
61 
62     return 0;
63 }

【luogu 2709】小B的询问

【题意】给一整数序列,值域为1~k,m个询问,每次询问区间内的每个数字出现次数的平方和

 

#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long 
using namespace std;
const int MAXN = 50010;
ll a[MAXN],cnt[MAXN],ans[MAXN],c;
int siz;
struct node
{
    int l, r, id;
    bool operator<(node a)
    {
        if (((l - 1) / siz) == ((a.l - 1) / siz))
            return r < a.r;
        return l / siz < a.l / siz;
    }
}mo[MAXN];
void add(int pos)
{
    c += 2 * cnt[pos] + 1;
    cnt[pos]++;
}
void del(int pos)
{
    c -= 2 * cnt[pos] - 1;
    cnt[pos]--;
}
int main()
{
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    siz = (int)sqrt(n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
    }
    for (int i = 1; i <= m; i++)
    {
        scanf("%d%d", &mo[i].l, &mo[i].r);
        mo[i].id = i;
    }
    sort(mo + 1, mo + 1 + m);
    int ansl=1, ansr=0;
    for (int i = 1; i <= m; i++)
    {
        int l = mo[i].l, r = mo[i].r;
        while (ansl > l) ansl--, add(a[ansl]);
        while (ansr < r) ansr++, add(a[ansr]);
        while (ansl < l) del(a[ansl]), ansl++;
        while (ansr > r) del(a[ansr]), ansr--;
        ans[mo[i].id] = c;
    }

    for (int i = 1; i <= m; i++)
        printf("%lld\n", ans[i]);


    return 0;
}

 

posted @ 2020-05-13 23:54  rentu  阅读(174)  评论(0编辑  收藏  举报