题意: cases T(1≤T≤10) (0<n,m≤30000) (0<ai≤30000)
      

    n个数ai 表示n个女孩所在教室

    m次询问 [L,R](1 <= L <= R <= n)
     

    问访问所有女孩的顺序方案数(进教室顺序)为多少(一次进教室只能访问一个人)
    
分析:

    莫队算法 + 排列数

    一个区间内的方案数为 C(m,c1)*C(m-c1,c2)*C(m-c1-c2,c3)*....*C(cn,cn)
      

    每次转移通过下式:

     C(m+1,n+1) = C(m,n) * (m+1/n+1)
         

     C(m,n) = C(m+1,n+1) * (n+1/m+1) (对于缩小的过程而言)
    
      因为需要对大素数取模,除法就是乘上对应的乘法逆元,故先用费马小定理

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int MOD = ;
const int MAXN = ;
const int MAXM = ;
struct Query
{
int L,R,id;
}node[MAXM];
struct Ans
{
long long a;
}ans[MAXM];
int a[MAXN],num[MAXN];
long long inv[MAXN];//乘法逆元
int t,n,m,unit;
void work()
{
long long temp = ;
memset(num,,sizeof(num));
int L = , R = ;
for(int i = ; i < m ; i++)
{
while(R < node[i].R)//C(m+1,n+1) = C(m,n)*(m+1/n+1)
{
R++;
num[a[R]]++;
temp = temp * (R - L + ) % MOD * inv[num[a[R]]] % MOD;
}
while(R > node[i].R)//C(m,n) = C(m+1,n+1)*(n+1/m+1)
{
temp = temp * num[a[R]] % MOD * inv[R - L + ] % MOD;
num[a[R]]--;
R--;
}
while(L < node[i].L)//C(m,n) = C(m+1,n+1)*(n+1/m+1)
{
temp = temp * num[a[L]] % MOD * inv[R - L + ] % MOD;
num[a[L]]--;
L++;
}
while(L > node[i].L)//C(m+1,n+1) = C(m,n)*(m+1/n+1)
{
L--;
num[a[L]]++;
temp = temp * (R - L + ) % MOD * inv[num[a[L]]] % MOD;
}
ans[node[i].id].a = temp;
}
}
bool cmp(Query a,Query b)
{
if(a.L/unit != b.L/unit) return a.L/unit < b.L/unit;
else return a.R < b.R;
}
void Init()//femat
{
inv[] = ;
for(int i = ; i < MAXN; i++)
inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
}
int main()
{
Init();
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = ; i <= n; i++)
scanf("%d",&a[i]);
for(int i = ; i < m; i++)
{
scanf("%d%d",&node[i].L,&node[i].R);
node[i].id = i;
}
unit = (int)sqrt(n);
sort(node,node+m,cmp);
work();
for(int i = ; i < m ;i++)
printf("%lld\n",ans[i].a);
}
}

最新文章

  1. DataGridView实现各种效果
  2. [转]Ubantu vmware tools 安装
  3. android开发中scrollview添加自定义view的滑动显示问题
  4. 斐波那契数列(Fibonacci)递归和非递归实现
  5. Document Set 【一】
  6. HDU 4638 Group ★(树状数组)
  7. Android 颜色渲染(七) RadialGradient 环形渲染实现水波纹效果
  8. HNCU1323:算法2-1:集合union (线性表)
  9. C语言_第二讲_规范以及常用数据类型
  10. Axure如何建立共享项目、如何编辑共享项目、如何获取共享项目
  11. kaggle入门项目:Titanic存亡预测(四)模型拟合
  12. String字符串类总结
  13. Linux知识要点大全(第一章)
  14. 如何在ADO中使用数据读取器(DataReader)读取数据
  15. 番外篇-AppService服务
  16. RNAseq测序reads定位
  17. SpUtil多样加密存储,兼容android9.0
  18. Linux音频驱动学习之:(1)ASOC分析
  19. Qt中窗口退出事件
  20. 输出1到n以内的素数

热门文章

  1. break,continue,return 区别
  2. java集合之Map_keySet_entrySet
  3. HibernateTemplate类的方法flush()
  4. kafka-manager安装
  5. Python之路第十三天,高级(7)-详述数据库一对多,多对多表关系的设计以及如何查询
  6. PHP结合Linux的cron命令实现定时任务
  7. C++之------虚函数
  8. Cognitive Radio Emergency Networks – Requirements and Design
  9. 找不到Qt5Cored.dll(Release和Debug版连接了不同的库)
  10. ListView中分割线的设置