算法学习:莫队

2021-01-23 01:14

阅读:717

标签:space   pac   turn   fine   long   return   不同   scanf   const   

【luogu P3901】数列找不同

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

 

 1 #include 2 #include 3 #include
 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  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 )
38     {
39         scanf("%d", &a[i]);
40     }
41     for (int i = 1; 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 )
49     {
50         int l = mo[i].l, r = mo[i].r;
51         while (ansl > l) ansl--, add(a[ansl]);
52         while (ansr , add(a[ansr]);
53         while (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 )
59         printf("%s\n", ans[i]?"Yes":"No");
60 
61 
62     return 0;
63 }

【luogu 2709】小B的询问

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

 

#include
#include
#include
#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  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 )
    {
        scanf("%d", &a[i]);
    }
    for (int i = 1; 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 )
    {
        int l = mo[i].l, r = mo[i].r;
        while (ansl > l) ansl--, add(a[ansl]);
        while (ansr , add(a[ansr]);
        while (ansl ;
        while (ansr > r) del(a[ansr]), ansr--;
        ans[mo[i].id] = c;
    }

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


    return 0;
}

 

算法学习:莫队

标签:space   pac   turn   fine   long   return   不同   scanf   const   

原文地址:https://www.cnblogs.com/rentu/p/12885858.html


评论


亲,登录后才可以留言!