BZOJ3809: Gty的二逼妹子序列
3809: Gty的二逼妹子序列
Time Limit: 80 Sec Memory Limit: 28 MBSubmit: 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
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
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 }