• 1878: [SDOI2009]HH的项链(离线+树状数组||在线主席树)


    1878: [SDOI2009]HH的项链

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 8511  Solved: 4099
    [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
     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <iomanip>
     6 #include <sstream>
     7 #include <vector>
     8 #include <map>
     9 using namespace std;
    10 const int maxn=5*1e4+5;
    11 const int maxm=2*1e5+2;
    12 map<int,int> ma;
    13 int cnt[maxn],arr[maxn],ans[maxm];
    14 int n,x,y,m;
    15 struct Node{ int x,y,id; }A[maxm];
    16 bool cmp(Node a,Node b){ return a.y<b.y; }  //按照右边的进行排序
    17 
    18 int lowbits(int x) { return x&-x; }
    19 void updata(int x,int value){
    20     while(x<=maxn){   //树状数组下标不能从0开始
    21         cnt[x]+=value;
    22         x+=lowbits(x);
    23     }
    24 }
    25 int query(int x){    //x是下标的位置
    26     int res=0;
    27     while(x>0){
    28         res+=cnt[x];
    29         x-=lowbits(x);
    30     }
    31     return res;
    32 }
    33 
    34 int main(){
    35     scanf("%d",&n);
    36     for(int i=1;i<=n;i++)  scanf("%d",&arr[i]);
    37     scanf("%d",&m);
    38     for(int i=1;i<=m;i++)  scanf("%d%d",&A[i].x,&A[i].y),A[i].id=i;    //离线
    39     sort(A+1,A+1+m,cmp);
    40     int L=1;
    41     for(int i=1;i<=m;i++){
    42         for(int j=L;j<=A[i].y;j++){
    43             if(ma[arr[j]]!=0) updata(ma[arr[j]],-1);   //如果前面有过消除前面的影响
    44             updata(j,1);   //更新
    45             ma[arr[j]]=j;   //更改下标的位置
    46         }
    47         L=A[i].y+1;
    48         ans[A[i].id]=query(A[i].y)-query(A[i].x-1);
    49     }
    50     for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    51     return 0;
    52 }
    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 using namespace std;
     6 const int maxn=5*1e4+5;
     7 const int maxm=2*1e5+5;
     8 int n,m,x,y,cnt;
     9 int arr[maxn],root[maxn],ma[1000006];
    10 struct Node{ int l,r,sum; }A[maxn*32];
    11 inline int read(){
    12     int x=0,f=1;
    13     char ch=getchar();
    14     while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    15     while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); }
    16     return x*f;
    17 }
    18 inline void write(int x){
    19     if(x<0) putchar('-'),x=-x;
    20     if(x>9) write(x/10);
    21     putchar(x%10+48);
    22 }
    23 void updata(int l,int r,int &now,int pre,int pos,int value){
    24     A[++cnt]=A[pre],now=cnt,A[cnt].sum+=value;
    25     if(l==r) return;
    26     int mid=l+r>>1;
    27     if(mid>=pos) updata(l,mid,A[now].l,A[pre].l,pos,value);
    28     else updata(mid+1,r,A[now].r,A[pre].r,pos,value);
    29 }
    30 int query(int l,int r,int pre,int now,int L,int R){
    31     if(L<=l&&R>=r) return A[now].sum-A[pre].sum;
    32     else{
    33         int mid=l+r>>1;
    34         if(L>mid) return query(mid+1,r,A[pre].r,A[now].r,L,R);
    35         else if(R<=mid) return query(l,mid,A[pre].l,A[now].l,L,R);
    36         else return query(l,mid,A[pre].l,A[now].l,L,mid)+query(mid+1,r,A[pre].r,A[now].r,mid+1,R);
    37     }
    38 }
    39 
    40 int main(){
    41     n=read();
    42     for(int i=1;i<=n;i++) arr[i]=read();
    43     for(int i=1;i<=n;i++){
    44         if(ma[arr[i]]==0) updata(1,n,root[i],root[i-1],i,1);
    45         else{
    46             int temp=0;
    47             updata(1,n,temp,root[i-1],ma[arr[i]],-1);
    48             updata(1,n,root[i],temp,i,1);
    49         }
    50         ma[arr[i]]=i;
    51     }
    52     m=read();
    53     for(int i=1,d1,d2;i<=m;i++){
    54         d1=read(),d2=read();
    55         write(query(1,n,root[d1-1],root[d2],d1,d2));
    56         putchar('
    ');
    57     }
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    6-查看centos中的用户和用户组
    23-python用BeautifulSoup用抓取a标签内所有数据
    22-python爬虫解决gbk乱码问题
    21-py3 发邮件
    20-调用百度AI的文字识别
    6-Ubuntu与Windows不能相互复制
    2018.4.18 Ubuntu 的telnet命令详解
    2018.4.17 java多线程练习二模拟开场仪式进场
    2018.4.16 Java多线程实现龟兔赛跑
    2018.4.15 Mac系统下如何使用StartUml画好需求分析的类图 (同样适用于windows)
  • 原文地址:https://www.cnblogs.com/qq-1585047819/p/11409475.html
Copyright © 2020-2023  润新知