zoukankan      html  css  js  c++  java
  • bzoj1878 [SDOI2009]HH的项链

    Description

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

    Input

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

    Output

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

    Sample Input

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

    Sample Output

    2
    2
    4

    HINT


    对于20%的数据,N ≤ 100,M ≤ 1000;
    对于40%的数据,N ≤ 3000,M ≤ 200000;
    对于100%的数据,N ≤ 50000,M ≤ 200000。


    正解:莫队算法

    莫队板子,巨水。。刷了难一点的就觉得这题没有任何难度了。。


    //It is made by wfj_2048~
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #define inf 1<<30
    #define il inline
    #define RG register
    #define ll long long
    #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    
    using namespace std;
    
    struct node{ int l,r,i,bl; }q[200010];
    
    int cnt[1000010],ans[200010],a[200010],n,m,block;
    
    il int gi(){
        RG int x=0,q=0; RG char ch=getchar();
        while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=1,ch=getchar();
        while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q ? -x : x;
    }
    
    il int cmp(const node &a,const node &b){ return a.bl<b.bl || (a.bl==b.bl && a.r<b.r); }
    
    il void work(){
        n=gi(); for (RG int i=1;i<=n;++i) a[i]=gi(); block=sqrt(n); m=gi();
        for (RG int i=1;i<=m;++i) q[i].l=gi(),q[i].r=gi(),q[i].i=i,q[i].bl=(q[i].l-1)/block+1;
        sort(q+1,q+m+1,cmp); RG int L=1,R=0,Ans=0;
        for (RG int i=1;i<=m;++i){
    	while (L>q[i].l){ L--,cnt[a[L]]++; if (cnt[a[L]]==1) Ans++; }
    	while (R<q[i].r){ R++,cnt[a[R]]++; if (cnt[a[R]]==1) Ans++; }
    	while (L<q[i].l){ cnt[a[L]]--; if (!cnt[a[L]]) Ans--; L++; }
    	while (R>q[i].r){ cnt[a[R]]--; if (!cnt[a[R]]) Ans--; R--; }
    	ans[q[i].i]=Ans;
        }
        for (RG int i=1;i<=m;++i) printf("%d
    ",ans[i]); return;
    }
    
    int main(){
        File("necklace");
        work();
        return 0;
    }
    


  • 相关阅读:
    Word Search
    Subsets
    Combinations
    Search a 2D Matrix
    求比正整数N大的最小正整数M,且M与N的二进制表示中有相同数目的1
    Set Matrix Zeroes
    Unity学习笔记—— 常用脚本函数
    学习 各个数据结构
    unity调用 安卓相册
    设置 相机跟随 主角及视角 滑动
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6416595.html
Copyright © 2011-2022 走看看