洛谷 P1972 [SDOI2009]HH的项链

洛谷 P1972 [SDOI2009]HH的项链

题目描述

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

输入格式:

 

第一行:一个整数N,表示项链的长度。

第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为0 到1000000 之间的整数)。

第三行:一个整数M,表示HH 询问的个数。

接下来M 行:每行两个整数,L 和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

 

输出格式:

 

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

 

 

输入样例#1: 
6
1 2 3 4 3 5
3
1 2
3 5
2 6
输出样例#1: 
2
2
4

说明

对于100%的数据,N <= 500000,M <= 200000。

题解:

莫队算法入门题之一。

不赘述,(见我的博客小Z的袜子)

哪位 dalao 能帮我看看下面的代码怎么优化?洛谷上 T 掉了2个点, BZOJ 上也 T 掉了。感谢了!!!

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=500005,M=200005;
 4 int n,m,block,col[N],belong[N],ans[M],sum,num[N*2];
 5 struct node{
 6     int l,r,id;
 7 }q[M];
 8 inline int read()
 9 {
10     int x=0,f=1; char ch=getchar();
11     while (!isdigit(ch))
12       f=(ch=='-')?-f:f,ch=getchar();
13     while (isdigit(ch))
14       x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
15     return x*f;
16 }
17 bool cmp(node a,node b)
18 {
19     return belong[a.l]==belong[b.l]?(belong[a.r]==belong[b.r]?a.id<b.id:a.r<b.r):a.l<b.l;
20 }
21 void revise(int x,int w)
22 {
23     num[col[x]]+=w; 
24     if (w>0) sum+=(num[col[x]]==1);
25     if (w<0) sum-=(num[col[x]]==0);
26 }
27 int main()
28 {
29     n=read();
30     block=sqrt(n);
31     for (int i=1; i<=n; i++)
32     {
33         scanf("%d",&col[i]);
34         belong[i]=i/block+1;
35     }
36     m=read();
37     for (int i=1; i<=m; i++)
38     {
39         int x,y;
40         x=read(),y=read();
41         q[i].l=x,q[i].r=y,q[i].id=i;
42     }
43     sort(q+1,q+1+m,cmp);
44     int zl=0,zr=0;
45     memset(num,0,sizeof(num)); sum=0;
46     for (int i=1; i<=m; i++)
47     {
48         while (zl<q[i].l) revise(zl,-1),zl++;
49         while (zl>q[i].l) revise(zl-1,1),zl--;
50         while (zr<q[i].r) revise(zr+1,1),zr++;
51         while (zr>q[i].r) revise(zr,-1),zr--;
52         ans[q[i].id]=sum;
53     }
54     for (int i=1; i<=m; i++)
55       printf("%d\n",ans[i]);
56     return 0;
57 }
View Code

加油加油加油!!! fighting fighting fighting !!!

猜你喜欢

转载自www.cnblogs.com/Frank-King/p/9167011.html