NIIFL的博客

NIIFL的博客

[SDOI2009]HH的项链

题目描述

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

分析

莫队入门题,离线读入,维护sum[颜色],当该区间内某一颜色从0加到1时,ans++,反之当某一颜色从1减到0时,ans–;

AC代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm> 
using namespace std;
const int MAXN=500005;
struct Mo{
    int l,r,id;
}q[MAXN];
int N,M,col[MAXN],Be[MAXN],unit;
int sum[MAXN],ans,put[MAXN];
bool cmp1(Mo a,Mo b){
    if(Be[a.l]==Be[b.l]) return a.r<b.r;
    else return a.l<b.l;
}
void revise(int x,int add){
    sum[col[x]]+=add; 
    if(!sum[col[x]]&&add==-1) ans--;
    else if(sum[col[x]]==1&&add==1) ans++; 
}
int main(){
    scanf("%d",&N); unit=sqrt(N); 
    for(int i=1;i<=N;i++) scanf("%d",&col[i]),Be[i]=i/unit+1;
    scanf("%d",&M); 
    for(int i=1;i<=M;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
    sort(q+1,q+M+1,cmp1);
    int l=0,r=0;
    for(int i=1;i<=M;i++){
        while(l<q[i].l) revise(l,-1),l++;
        while(l>q[i].l) revise(l-1,1),l--;
        while(r<q[i].r) revise(r+1,1),r++;
        while(r>q[i].r) revise(r,-1),r--;
        put[q[i].id]=ans;
    }
    for(int i=1;i<=M;i++) 
        printf("%d\n",put[i]);
    return 0; 
}
阅读更多
个人分类: 莫队算法
上一篇[国家集训队]小Z的袜子——莫队算法学习笔记
下一篇HDU 2089 不要62
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭