• 洛谷P1972 [SDOI2009]HH的项链


    题目背景

    题目描述

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

    输入输出格式

    输入格式:

     

    第一行:一个整数N,表示项链的长度。

    第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。

    第三行:一个整数M,表示HH 询问的个数。

    接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

     

    输出格式:

     

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

     

    输入输出样例

    输入样例#1:
    6
    1 2 3 4 3 5
    3
    1 2
    3 5
    2 6
    
    输出样例#1:
    2
    2
    4

    说明

    数据范围:

    对于100%的数据,N <= 50000,M <= 200000。

    区间无修改查询。

    模板级别的莫队。

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 const int mxn=50010;
    10 const int mxm=200010;
    11 int read(){
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 struct query{
    18     int l,r;
    19     int m,id;
    20 }c[mxm];
    21 inline int cmp(query a,query b){
    22     if(a.m!=b.m)return a.m<b.m;
    23     return a.r<b.r;
    24 }
    25 int n,m;
    26 int a[mxn];
    27 int cnt[mxm*2],ans[mxn];
    28 void work(){
    29     register int l=1,r=0;
    30     int tmp=0;
    31     int i;
    32     for(i=1;i<=m;++i){
    33         while(r<c[i].r){
    34             r++;
    35             cnt[a[r]]++;
    36             if(cnt[a[r]]==1) ++tmp;
    37         }
    38         while(l<c[i].l){
    39             cnt[a[l]]--;
    40             if(!cnt[a[l]]) --tmp;
    41             l++;
    42         }
    43         while(r>c[i].r){
    44             cnt[a[r]]--;
    45             if(!cnt[a[r]]) --tmp;
    46             r--;
    47         }
    48         while(l>c[i].l){
    49             l--;
    50             cnt[a[l]]++;
    51             if(cnt[a[l]]==1) ++tmp;
    52         }
    53         ans[c[i].id]=tmp;
    54     }
    55     for(i=1;i<=m;i++)printf("%d
    ",ans[i]);
    56     return;
    57 }
    58 int main(){
    59     n=read();
    60     int i,j;
    61     for(register int i=1;i<=n;++i){ a[i]=read(); }
    62     m=read();
    63     int block=sqrt(n);
    64     for(register int i=1;i<=m;++i){
    65         c[i].l=read();c[i].r=read();
    66         c[i].id=i;
    67         c[i].m=(c[i].l-1)/block+1;
    68     }
    69     sort(c+1,c+m+1,cmp);
    70     work();
    71     return 0;
    72 }
  • 相关阅读:
    Note/Solution 转置原理 & 多点求值
    Note/Solution 「洛谷 P5158」「模板」多项式快速插值
    Solution 「CTS 2019」「洛谷 P5404」氪金手游
    Solution 「CEOI 2017」「洛谷 P4654」Mousetrap
    Solution Set Border Theory
    Solution Set Stirling 数相关杂题
    Solution 「CEOI 2006」「洛谷 P5974」ANTENNA
    Solution 「ZJOI 2013」「洛谷 P3337」防守战线
    Solution 「CF 923E」Perpetual Subtraction
    KVM虚拟化
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5981825.html
Copyright © 2020-2023  润新知