This is about a number of n numbers, and then the numbers in the L and R range, how many options are there,
Here we divide this n-length string into sqrt (n) blocks and then a property their L belongs to that fast with this as the first keyword, then in accordance with R for the second keyword, then sort each query interval
We know that when l they belong to a piece of time, R is gradually increasing, then transferred sqrt (n) *a+n and then with this scheme approach complexity close to n^ (1.5)
#include <iostream>#include<algorithm>#include<string.h>#include<vector>#include<cstdio>#include<cmath>using namespaceStd;typedefLong LongLL;Const intMAXN =30005;ConstLL mod =1000000007;structseg{intL,r,id;} P[MAXN];intB[MAXN];voidGCD (ll A, ll B, LL &d, LL &x, LL &y) { if(b==0) {D=a; x=1; y=0; }Else{gcd (b,a%B,D,Y,X); Y-=x* (A/b); }}LL INV (ll a) {ll d, x, y; GCD (A,mod,d,x,y); returnd==1? (X+mod)%mod:-1;} LL A[MAXN],ANS[MAXN],NUM[MAXN],AA,NIA[MAXN];intC[MAXN];BOOLCMP (seg A, seg B) {returnB[A.L]==B[B.L]? a.r<b.r:b[a.l]<B[B.L];}voidUpdateintXintadd) {AA= (AA * nia[num[x])%MoD; NUM[X]+=add; AA= (AA * a[num[x]])%MoD;}voidSolveintm) {memset (num,0,sizeof(num)); AA=1; LL L=1, r=0; for(intI=0; i<m; i++){ while(r<P[i]. R) {R++; Update (C[r],1); } while(r>P[i]. R) {update (c[r],-1); r--; } while(l<P[i]. L) {update (c[l],-1); l++; } while(l>P[i]. L) {L--; Update (C[l],1); } ans[P[i].id]= (INV (AA) *a[p[i]. R-p[i]. L +1])%MoD; } for(intI=0; i<m; i++) {printf ("%i64d\n", Ans[i]); }}intMain () {a[0]=1; nia[0]=INV (1); for(LL i=1; i<maxn-1; i++) {A[i]= (a[i-1]*i)%MoD; Nia[i]=INV (a[i]); } intCAs; scanf ("%d",&CAs); for(intCc=1; cc<=cas; ++cc) { intn,m; scanf ("%d%d",&n,&m); intBOLOC=SQRT (n+0.5); for(intI=1; i<=n; i++) {B[i]= (I-1)/boloc+1; } for(intI=1; i<=n; i++) scanf ("%d",&C[i]); for(intI=0; i<m; i++) {p[i].id=i; scanf"%d%d", &p[i]. l,&P[i]. R); } sort (P,p+m,cmp); Solve (m); } return 0;}
hdu5145-Mo Team algorithm