• SPOJ 3267 求区间不同数的个数


    题意:给定一个数列,每次查询一个区间不同数的个数。

    做法:离线+BIT维护。将查询按右端点排序。从左到右扫,如果该数之前出现过,则将之前出现过的位置相应删除;当前位置则添加1。这样做就保证每次扫描到的某一位置,以该位置为右端点的区间都相应地确定了。

     1 /*
     2  *Author:       Zhaofa Fang
     3  *Created time: 2013-08-25-22.29 星期日
     4  */
     5 #include <cstdio>
     6 #include <cstdlib>
     7 #include <sstream>
     8 #include <iostream>
     9 #include <cmath>
    10 #include <cstring>
    11 #include <algorithm>
    12 #include <string>
    13 #include <utility>
    14 #include <vector>
    15 #include <queue>
    16 #include <map>
    17 #include <set>
    18 using namespace std;
    19 
    20 typedef long long ll;
    21 typedef pair<int,int> PII;
    22 #define DEBUG(x) cout<< #x << ':' << x << endl
    23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
    24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
    25 #define REP(i,n) for(int i=0;i<(n);i++)
    26 #define REPD(i,n) for(int i=(n-1);i>=0;i--)
    27 #define PII pair<int,int>
    28 #define PB push_back
    29 #define ft first
    30 #define sd second
    31 #define lowbit(x) (x&(-x))
    32 #define INF (1<<30)
    33 #define eps (1e-8)
    34 
    35 const int maxq = 200011;
    36 const int maxn = 30011;
    37 int a[maxn],C[maxn],last[1000011];
    38 int ans[maxq];
    39 void init(){
    40     memset(C,0,sizeof(C));
    41     memset(last,-1,sizeof(last));
    42 }
    43 struct Query{
    44     int l,r;
    45     int idx;
    46     bool operator < (const Query & rhs)const{
    47         return r < rhs.r;
    48     }
    49 }Q[maxq];
    50 
    51 void add(int x,int val){
    52     while(x<maxn){
    53         C[x] += val;
    54         x += lowbit(x);
    55     }
    56 }
    57 int sum(int x){
    58     int res = 0;
    59     while(x > 0){
    60         res += C[x];
    61         x -= lowbit(x);
    62     }
    63     return res;
    64 }
    65 int main(){
    66     //freopen("in","r",stdin);
    67     //freopen("out","w",stdout);
    68     int n;
    69     while(~scanf("%d",&n)){
    70         init();
    71         FOR(i,1,n)scanf("%d",&a[i]);
    72         int q;
    73         scanf("%d",&q);
    74         REP(i,q){
    75             scanf("%d%d",&Q[i].l,&Q[i].r);
    76             Q[i].idx = i;
    77         }
    78         sort(Q,Q+q);
    79         int pre = 1;
    80         REP(i,q){
    81             FOR(j,pre,Q[i].r){
    82                 if(last[a[j]]==-1){
    83                     add(j,1);
    84                 }else {
    85                     add(last[a[j]],-1);
    86                     add(j,1);
    87                 }
    88                 last[a[j]] = j;
    89             }
    90             ans[Q[i].idx] = sum(Q[i].r)-sum(Q[i].l-1);
    91             pre = Q[i].r+1;
    92         }
    93         REP(i,q)printf("%d
    ",ans[i]);
    94     }
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    欧拉计划之题目7:找出第10001个质数
    DShow实现一个avi视频的播放(含有个人解释和注释)
    DirectX 9 SDK安装后在vs2010里编译BaseClasses出错问题解决方法
    C#内存占用大量资源的解决办法
    C#读写ini文件操作
    【Java】编程技术经典书籍列表
    【数据库_Mysql】查询当前年份的sql
    【数据库_Mysql】MySQL动态语句 if set choose where foreach trim
    【JavaScript】20款漂亮的css字体
    【数据库_Mysql】<foreach>标签在Mysql中的使用
  • 原文地址:https://www.cnblogs.com/fzf123/p/3281744.html
Copyright © 2020-2023  润新知