• BZOJ 1878 [SDOI2009]HH的项链 【莫队】


    任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=1878

    1878: [SDOI2009]HH的项链

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 7548  Solved: 3718
    [Submit][Status][Discuss]

    Description

    HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一
    段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此他的项链变得越来越长。有一天,他突然提出了一
    个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只
    好求助睿智的你,来解决这个问题。

    Input

    第一行:一个整数N,表示项链的长度。 
    第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 
    第三行:一个整数M,表示HH询问的个数。 
    接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
    N ≤ 50000,M ≤ 200000。

    Output

    M行,每行一个整数,依次表示询问对应的答案。

    Sample Input

    6
    1 2 3 4 3 5
    3
    1 2
    3 5
    2 6

    Sample Output

    2
    2
    4

    解题思路:

    莫队裸题,转移的时候判断数字是否唯一即可。

    AC code:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN = 5e4+10;
     4 const int MAXU = 1e6+10;
     5 const int MAXQ = 2e5+10;
     6 int N, M, lim;
     7 int sum[MAXU];
     8 int a[MAXN];
     9 int ans[MAXQ];
    10 struct Query
    11 {
    12     int l, r, id;
    13 }Q[MAXQ];
    14 
    15 bool cmp(Query a, Query b){
    16     int la = a.l/lim, lb = b.l/lim;
    17     if(la != lb) return la < lb;
    18     return a.r < b.r;
    19 }
    20 
    21 int Move(int x, int v)
    22 {
    23     int res = 0;
    24     if(v == 1 && sum[a[x]] == 0) res++;
    25     if(v == -1 && sum[a[x]] == 1) res--;
    26     sum[a[x]]+=v;
    27     return res;
    28 }
    29 
    30 int main()
    31 {
    32     scanf("%d", &N);
    33     for(int i = 1; i <= N; i++){
    34         scanf("%d", &a[i]);
    35     }
    36     lim = sqrt(N);
    37     scanf("%d", &M);
    38     for(int i = 1; i <= M; i++){
    39         scanf("%d %d", &Q[i].l, &Q[i].r);
    40         Q[i].id = i;
    41     }
    42 
    43     sort(Q+1, Q+1+M, cmp);
    44 
    45     int cur = 0, L = 1, R = 0;
    46     for(int i = 1; i <= M; i++){
    47         while(Q[i].l < L) cur+=Move(--L, 1);
    48         while(Q[i].l > L) cur+=Move(L++, -1);
    49         while(Q[i].r < R) cur+=Move(R--, -1);
    50         while(Q[i].r > R) cur+=Move(++R, 1);
    51         ans[Q[i].id] = cur;
    52     }
    53 
    54     for(int i = 1; i <= M; i++){
    55         printf("%d
    ", ans[i]);
    56     }
    57 
    58     return 0;
    59 
    60 }
  • 相关阅读:
    编程心得2----有疑惑,用代码说话
    Java的static关键字
    html中设置textbox的宽和高
    C#(winform)设置窗体的启动位置
    C#(winform)设置窗口置顶
    C#(winform)实现不同DPI控件自适应1
    设计模式--策略模式(strategy)
    requirejs原理深究以及r.js和gulp的打包【转】
    JavaScript中清空数组的三种方式
    localstorage本地存储
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10403069.html
Copyright © 2020-2023  润新知