2 4 2 1 2 1 3 1 3 1 4 1 1 1 1 1
3 12 1
BestCoder Round #22
题目大意:
每组两个数 n m分别表示人数n和询问次数m
之后n个数 表示n个女孩所在教室
对于m次询问 每次一个[L,R](1 <= L <= R <= n) 问为了访问到每个女孩 访问教室的方案有几种(会出现几个女孩在一个教室的情况 但每次访问教室只能找一个女孩 同一个编号的教室是相同的)
思路:
莫队+逆元
设将要进入的人的教室号是i,已经进去的人有y个,num[x]表示的是当前这个区间[L,R]中在x教室的有多少人,则当这个人进去之后总的方案数可这样思考:
总共有y+1个位置,先放num[i]+1个教室,有C(y+1,num[i]+1),原来先放num[i]个教师,有C(y,num[i]),所以会扩大C(y+1,num[i]+1)/C(y,num[i])倍
每个人出去的时候也是同样的考虑方法
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define inf -0x3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a, b) memset(a, b, sizeof(a)) typedef long long ll; const int maxn=40100; const __int64 MOD=1e9+7; int n,m; int num[maxn],a[maxn]; __int64 ans[maxn],c[maxn]; struct node{ int l,r,id; }Q[maxn]; int unit; bool cmp(node u,node v){ if(u.l/unit!=v.l/unit) return u.l/unit<v.l/unit; return u.r<v.r; } __int64 inv(__int64 a,__int64 M){ if(a==1) return 1; return inv(M%a,M)*(M-M/a)%M; } void solve(){ int L=1,R=0; __int64 temp=1; for(int i=1;i<=m;i++){ while(R>Q[i].r){ temp=temp*num[a[R]]%MOD*c[R-L+1]%MOD; num[a[R]]--; R--; } while(R<Q[i].r){ R++; num[a[R]]++; if((R-L+1)%num[a[R]]==0) temp=temp*(R-L+1)/num[a[R]]%MOD; else temp=temp*(R-L+1)%MOD*c[num[a[R]]]%MOD; } while(L>Q[i].l){ L--; num[a[L]]++; if((R-L+1)%num[a[L]]==0) temp=temp*(R-L+1)/num[a[L]]%MOD; else temp=temp*(R-L+1)%MOD*c[num[a[L]]]%MOD; } while(L<Q[i].l){ temp=temp*num[a[L]]%MOD*c[R-L+1]%MOD; num[a[L]]--; L++; } ans[Q[i].id]=temp; } } int main(){ int _; for(int i=1;i<=30000;i++) c[i]=inv(i,MOD); scanf("%d",&_); while(_--){ memset(num,0,sizeof(num)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++){ scanf("%d%d",&Q[i].l,&Q[i].r); Q[i].id=i; } unit=(int)sqrt(n); sort(Q+1,Q+m+1,cmp); solve(); for(int i=1;i<=m;i++) printf("%I64d\n",ans[i]); } return 0; }