給你一個長度爲N的序列ai,1≤i≤N和q組詢問,每組詢問讀入l1,r1,l2,r2,需輸出
get(l,r,x)表示計算區間[l,r]中,數字x出現了多少次。
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define LL long long 6 using namespace std; 7 int sz,N,Q,num; 8 int a[50010]; 9 LL MAP[233][50010],inlineMAP[50010]; 10 LL ANS[233]; 11 struct ss{ 12 int L,R,pos,id; 13 LL flag; 14 }qrr[100010]; 15 LL ans[50010]; 16 bool cmp(ss a,ss b){ 17 return a.pos<b.pos; 18 } 19 LL get(int ,int ); 20 int main() 21 { 22 int i,j,k; 23 scanf("%d",&N); 24 sz=sqrt(N); 25 for(i=num=1;i<=N;i+=sz,num++){ 26 for(j=i;j<i+sz&&j<=N;j++){ 27 scanf("%d",&a[j]); 28 MAP[num][a[j]]++; 29 } 30 } 31 num--; 32 scanf("%d",&Q); 33 for(i=1;i<=Q;i++){ 34 scanf("%d%d%d%d",&qrr[i].L,&qrr[i].R,&qrr[i].pos,&qrr[i+Q].pos); 35 qrr[i+Q].L=qrr[i].L,qrr[i+Q].R=qrr[i].R; 36 qrr[i+Q].id=qrr[i].id=i; 37 qrr[i].flag=-1,qrr[i+Q].flag=1; 38 qrr[i].pos--; 39 } 40 sort(qrr+1,qrr+Q+Q+1,cmp); 41 j=0; 42 for(i=1;i<=Q<<1;i++){ 43 while(j<qrr[i].pos){ 44 j++; 45 inlineMAP[a[j]]++; 46 for(k=1;k<=num;k++) 47 ANS[k]+=MAP[k][a[j]]; 48 } 49 ans[qrr[i].id]+=qrr[i].flag*get(qrr[i].L,qrr[i].R); 50 } 51 for(i=1;i<=Q;i++) 52 printf("%lld\n",ans[i]); 53 return 0; 54 } 55 LL get(int L,int R){ 56 LL ret=0; 57 int i,j,k; 58 int l,r; 59 if(R-L+1<=sz){ 60 for(i=L;i<=R;i++) 61 ret+=inlineMAP[a[i]]; 62 return ret; 63 } 64 for(i=j=1;i<L;i+=sz,j++); 65 l=i-1; 66 for(;i+sz<=R+1&&i<=N;j++,i+=sz) 67 ret+=ANS[j]; 68 r=i; 69 for(i=L;i<=l;i++) 70 ret+=inlineMAP[a[i]]; 71 for(i=r;i<=R;i++) 72 ret+=inlineMAP[a[i]]; 73 return ret; 74 }
或許有樹套樹的作法?php