BZOJ3809: Gty的二逼妹子序列

3809: Gty的二逼妹子序列

Time Limit: 80 Sec  Memory Limit: 28 MB
Submit: 1131  Solved: 312
[Submit][Status][Discuss]

Description

Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。
 
对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。
 
为了方便,我们规定妹子们的美丽度全都在[1,n]中。
 
给定一个长度为n(1<=n<=100000)的正整数序列s(1<=si<=n),对于m(1<=m<=1000000)次询问“l,r,a,b”,每次输出sl...sr中,权值∈[a,b]的权值的种类数。

 

Input

第一行包括两个整数n,m(1<=n<=100000,1<=m<=1000000),表示数列s中的元素数和询问数。
 
第二行包括n个整数s1...sn(1<=si<=n)。
 
接下来m行,每行包括4个整数l,r,a,b(1<=l<=r<=n,1<=a<=b<=n),意义见题目描述。
 
保证涉及的所有数在C++的int内。
 
保证输入合法。

 

Output

对每个询问,单独输出一行,表示sl...sr中权值∈[a,b]的权值的种类数。

 

Sample Input

10 10
4 4 5 1 4 1 5 1 2 1
5 9 1 2
3 4 7 9
4 4 2 5
2 3 4 7
5 10 4 4
3 9 1 1
1 4 5 9
8 9 3 3
2 2 1 6
8 9 1 4

Sample Output

2
0
0
2
1
1
1
0
1
2

HINT

 

样例的部分解释:

 

5 9 1 2

子序列为4 1 5 1 2

在[1,2]里的权值有1,1,2,有2种,因此答案为2。

 

3 4 7 9

子序列为5 1

在[7,9]里的权值有5,有1种,因此答案为1。

 

4 4 2 5

子序列为1

没有权值在[2,5]中的,因此答案为0。

 

2 3 4 7

子序列为4 5

权值在[4,7]中的有4,5,因此答案为2。

 

建议使用输入/输出优化。

 

 
莫队+树状数组。但是好慢啊!!!!我70多秒过的……
据说可以莫队+分块,很快,可惜我不会。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define inf 1<<30
 7 #define maxn 100005
 8 #define maxm 1000005
 9 using namespace std;
10 int n,m,a[maxn],pos[maxn],ans[maxm],t[maxn],sum[maxn];
11 struct fuck{int l,r,id,a,b;}pps[maxm];
12 int read(){
13     int x=0,f=1;char ch;
14     for(ch=getchar();ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
15     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
16     return x*f;
17 }
18 bool comp(fuck a,fuck b){
19     if(pos[a.l]==pos[b.l])
20         if(pos[a.l]&1) return a.r<b.r;
21         else return a.r>b.r;
22     return pos[a.l]<pos[b.l];
23 }
24 void change(int x,int y){for(int i=x;i<=n;i+=i&-i)t[i]+=y;}
25 void updata(int x,int y){
26     sum[x]+=y;
27     if(y==-1&&sum[x]==0) change(x,y);
28     if(y==1&&sum[x]==1) change(x,y);
29 }
30 int query(int x){int y=0;for(int i=x;i;i-=x&-i)y+=t[i];return y;}
31 int main(){
32     n=read(); m=read(); int sn=sqrt(n);
33     for(int i=1;i<=n;i++) pos[i]=(i-1)/sn+1;
34     for(int i=1;i<=n;i++) a[i]=read();
35     for(int i=1;i<=m;i++) pps[i].l=read(),pps[i].r=read(),pps[i].a=read(),pps[i].b=read(),pps[i].id=i;
36     sort(pps+1,pps+m+1,comp);
37     for(int i=1,l=0,r=0;i<=m;i++){
38         for(;l<pps[i].l;l++) updata(a[l],-1);
39         for(;l>pps[i].l;l--) updata(a[l-1],1);
40         for(;r<pps[i].r;r++) updata(a[r+1],1);
41         for(;r>pps[i].r;r--) updata(a[r],-1);
42         ans[pps[i].id]=query(pps[i].b)-query(pps[i].a-1);
43     }
44     for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
45     return 0;
46 }
View Code

 

posted @ 2016-06-10 11:21  I'mLS  阅读(144)  评论(0编辑  收藏  举报