Gty的二逼妹子序列
阿新 • • 發佈:2018-11-22
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
首先想到高階數結,然後發現28M???時限80s???
這是逼著我莫隊嗎?結果一算空間,還真是卡著讓你莫隊。。。
注意最後統計答案的時候不能用樹狀陣列。。。要分塊。。。
/*program from Wolfycz*/ #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define inf 0x7f7f7f7f #define lowbit(x) ((x)&(-x)) using namespace std; typedef long long ll; typedef unsigned int ui; typedef unsigned long long ull; inline char gc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline int frd(){ int x=0,f=1; char ch=gc(); for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; } inline int read(){ int x=0,f=1; char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; } inline void print(int x){ if (x<0) putchar('-'),x=-x; if (x>9) print(x/10); putchar(x%10+'0'); } const int N=1e5,M=1e6; int pos[N+10],col[N+10],Ans[M+10],cnt[N+10]; int n,m,size; struct S1{ int l,r,ID,a,b; void insert(int i){l=read(),r=read(),a=read(),b=read(),ID=i;} bool operator <(const S1 &tis)const{return pos[l]!=pos[tis.l]?l<tis.l:r<tis.r;} }A[M+10]; struct S2{ int val[350]; void insert(int x,int v){val[pos[x]]+=v;} int Query(int l,int r){ int res=0; for (int i=l;i<=min(pos[l]*size,r);i++) res+=(cnt[i]>0); if (pos[l]!=pos[r]) for (int i=(pos[r]-1)*size+1;i<=r;i++) res+=(cnt[i]>0); for (int i=pos[l]+1;i<pos[r];i++) res+=val[i]; return res; } }Block; void insert(int x,int v){ int tmp=cnt[col[x]]+v; if (cnt[col[x]]&&!tmp) Block.insert(col[x],-1); if (!cnt[col[x]]&&tmp) Block.insert(col[x], 1); cnt[col[x]]+=v; } int main(){ n=read(),m=read(),size=(int)(sqrt(n)); for (int i=1;i<=n;i++) col[i]=read(),pos[i]=(i-1)/size+1; for (int i=1;i<=m;i++) A[i].insert(i); sort(A+1,A+1+m); for (int i=1,l=1,r=0;i<=m;i++){ while (r<A[i].r) insert(++r, 1); while (r>A[i].r) insert(r--,-1); while (l<A[i].l) insert(l++,-1); while (l>A[i].l) insert(--l, 1); Ans[A[i].ID]=Block.Query(A[i].a,A[i].b); } for (int i=1;i<=m;i++) print(Ans[i]),putchar('\n'); return 0; }