NPY and girls [莫隊+逆元]
阿新 • • 發佈:2018-12-16
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #define N 30050 #define LL long long #define Mod 1000000007 using namespace std; int a[N],T,n,m,cnt[N],pos[N]; LL s[N],inv[N],ans[N],now,x,y; struct Node{int l,r,id;}q[N]; void Init(){ memset(ans,0,sizeof(ans)); memset(cnt,0,sizeof(cnt)); memset(pos,0,sizeof(pos)); now=1; } void exgcd(int a,int b){ if(!b){x=1,y=0; return;} exgcd(b,a%b); int x1=y , y1=x-a/b*y; x=x1 , y=y1; } bool cmp(Node a,Node b){ if(pos[a.l]==pos[b.l]) return a.r<b.r; return pos[a.l]<pos[b.l]; } void add(int x){ now = (now * inv[cnt[x]]) % Mod; now = (now * s[++cnt[x]]) % Mod; } void del(int x){ now = (now * inv[cnt[x]]) % Mod; now = (now * s[--cnt[x]]) % Mod; } int main(){ s[0] = inv[0] = 1; for(int i=1;i<=N-50;i++){ s[i] = (s[i-1] * i) % Mod; exgcd(s[i],Mod); inv[i] = (x+Mod) % Mod; } scanf("%d",&T); while(T--){ Init(); scanf("%d%d",&n,&m); int siz = sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),pos[i] = i/siz; for(int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+m+1,cmp); int l=1,r=0; for(int i=1;i<=m;i++){ while(r<q[i].r) add(a[++r]); while(r>q[i].r) del(a[r--]); while(l<q[i].l) del(a[l++]); while(l>q[i].l) add(a[--l]); exgcd(now,Mod); x = (x+Mod) % Mod; ans[q[i].id] = (s[r-l+1] * x) % Mod; } for(int i=1;i<=m;i++) printf("%lld\n",ans[i]); } return 0; }