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

    题意:给定n个数,m个询问,每次求一段区间内有多少种不同的数。n<=50000,m<=200000

    题解:很显然是莫队傻逼题。

    #include<iostream>
    #include<cstdio> 
    #include<algorithm>
    #include<cmath>
    #define MAXN 50000
    #define MN 200000
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    
    int n,m,size;
    int s[MAXN+5],pos[MAXN+5],ans[MN+5];
    int num[1000005],kind=0;
    struct ques{int l,r,num;}q[MN+5];
    
    bool cmp(ques x,ques y){return pos[x.l]==pos[y.l]?x.r<y.r:pos[x.l]<pos[y.l];}
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)s[i]=read();
        m=read();size=sqrt(n);
        for(int i=1;i<=n;i++)pos[i]=(i-1)/size+1;
        for(int i=1;i<=m;i++)
            q[i].l=read(),q[i].r=read(),q[i].num=i;
         sort(q+1,q+m+1,cmp);
         int l=1,r=1;kind=1;num[s[1]]=1;
         for(int i=1;i<=m;i++)
         {
             while(l<q[i].l) if(!--num[s[l++]]) kind--;
             while(r>q[i].r) if(!--num[s[r--]]) kind--;
            while(r<q[i].r) if(++num[s[++r]]==1) kind++;
            while(l>q[i].l) if(++num[s[--l]]==1) kind++;    
            ans[q[i].num]=kind;
        }
        for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    P1828 [USACO3.2]香甜的黄油 Sweet Butter 题解
    P2058 海港 题解
    浅谈三分算法
    海伦公式的证明
    一年一回首
    再谈单调队列优化 & 背包九讲
    浅谈单调队列
    P1440 求m区间内的最小值 题解
    CF1374B Multiply by 2, divide by 6 题解
    组合数、杨辉三角与递推算法
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj1878.html
Copyright © 2011-2022 走看看