传送门

题意

给出n个数,m次访问,每次询问[L,R]的数有多少种排列

分析

\(n,m<=30000\),我们采用莫队算法,关键在于区间如何\(O(1)\)转移,由排列组合知识得到,如果加入一个数,\(区间值*区间长度/该数出现次数\),减去一个数则相反操作讲解

trick

1.我的原先莫队写法不能ac,原因是我传入的L,R是全局变量,在insert和erase前就++,--了,而没有达到预期目的,把R++,L--分离即可

代码

//wa
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod = 1e9+7;
int t,n,m,len,L,R;
int a[30030],cnt[30030];
ll ans[30030],ret;
struct node
{
int l,r,id,block;
node(){}
node(int l,int r,int id):l(l),r(r),id(id){block=l/len;}
bool operator<(const node &p)const
{
return block==p.block?r<p.r:block<p.block;
}
}e[30030];
ll inv[30030];
void get_inverse(int n, ll p) {
inv[1] = 1;
for (int i = 2; i <= n; ++i) {
inv[i] = (p - p / i) * inv[p % i] % p;
}
}
void insert(int loc)
{
cnt[a[loc]]++;
//printf("l=%d r=%d\n",L,R);
ret=ret*(R-L+1)%mod;
ret=ret*inv[cnt[a[loc]]]%mod;
//printf("ret=%lld\n",ret);
}
void erase(int loc)
{
ret=ret*cnt[a[loc]]%mod;
ret=ret*inv[R-L+1]%mod;
cnt[a[loc]]--;
}
int main()
{
get_inverse(30000,mod);
for(scanf("%d",&t);t--;)
{
scanf("%d %d",&n,&m);
F(i,1,n) scanf("%d",a+i);
len=sqrt(n);
F(i,1,m)
{
int left,right;
scanf("%d %d",&left,&right);
e[i]=node(left,right,i);
}
sort(e+1,e+1+m);
L=1,R=0;
ret=1;
mem(ans,0);mem(cnt,0);
//F(i,1,n) printf("%lld%c",inv[i],i==n?'\n':' ');
F(i,1,m)
{
//printf("ret1=%lld\n",ret);
while(R<e[i].r) insert(++R);
while(L>e[i].l) insert(--L);
while(R>e[i].r) erase(R--);
while(L<e[i].l) erase(L++);
ans[e[i].id]=ret;
//printf("ret2=%lld\n",ret);
}
F(i,1,m) printf("%lld\n",ans[i]);
}
return 0;
}
//ac
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod = 1000000007;
int t,n,m,len,L,R;
int a[30030],cnt[30030];
ll ans[30030],inv[30030];
ll ret;
struct node
{
int l,r,id,block;
node(){}
node(int _l,int _r,int _id):l(_l),r(_r),id(_id){block=l/len;}
bool operator<(const node &p)const
{
return block==p.block?r<p.r:block<p.block;
}
}e[30030];
ll pow_mod(ll a,ll p)
{
ll ans=1;
for(ll ret=a;p;p>>=1,ret=ret*ret%mod) if(p&1) ans=ans*ret%mod;
return ans%mod;
}
void insert(int loc)
{
cnt[a[loc]]++;
//printf("l=%d r=%d\n",L,R);
ret=ret*(R-L+1)%mod;
ret=ret*inv[cnt[a[loc]]]%mod;
//printf("ret=%lld\n",ret);
}
void erase(int loc)
{
ret=ret*cnt[a[loc]]%mod;
ret=ret*inv[R-L+1]%mod;
cnt[a[loc]]--;
}
int main()
{
F(i,1,30000) inv[i]=pow_mod(i,mod-2);
for(scanf("%d",&t);t--;)
{
scanf("%d %d",&n,&m);
F(i,1,n) scanf("%d",a+i);
len=sqrt(n);
F(i,1,m)
{
int left,right;
scanf("%d %d",&left,&right);
e[i]=node(left,right,i);
}
sort(e+1,e+1+m);
ret=1;
mem(ans,0);mem(cnt,0);
L=1;R=0;
//F(i,1,n) printf("%lld%c",inv[i],i==n?'\n':' ');
F(i,1,m)
{
//printf("ret1=%lld\n",ret);
while(R<e[i].r) {++R;insert(R);}
while(L>e[i].l) {--L;insert(L);}
while(R>e[i].r) {erase(R);R--;}
while(L<e[i].l) {erase(L);L++;}
ans[e[i].id]=ret;
//printf("ret2=%lld\n",ret);
}
F(i,1,m) printf("%lld\n",ans[i]);
}
return 0;
}

HDU5145:5145 ( NPY and girls ) (莫队算法+排列组合+逆元)的更多相关文章

  1. HDU 5145 NPY and girls 莫队+逆元

    NPY and girls Problem Description NPY's girlfriend blew him out!His honey doesn't love him any more! ...

  2. NPY and girls-HDU5145莫队算法

    Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description ...

  3. hdu_5145_NPY and girls(莫队算法+组合)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5145 题意:给你n,m,共有n个女孩,标号为1—n,n个数xi表示第ith个女孩在第xi个教室,然后下 ...

  4. HDU 5145 - NPY and girls

    题意: cases T(1≤T≤10) (0<n,m≤30000) (0<ai≤30000)    n个数ai 表示n个女孩所在教室 m次询问 [L,R](1 <= L <= ...

  5. HDU 5145 NPY and girls(莫队算法+乘法逆元)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5145 [题目大意] 给出一个数列,每次求一个区间数字的非重排列数量.答案对1e9+7取模. [题解 ...

  6. hdu 5145(莫队算法+逆元)

    NPY and girls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  7. NBUT 1457 莫队算法 离散化

    Sona Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format: Submit Status Practice NBUT 145 ...

  8. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7687  Solved: 3516[Subm ...

  9. Codeforces617 E . XOR and Favorite Number(莫队算法)

    XOR and Favorite Number time limit per test: 4 seconds memory limit per test: 256 megabytes input: s ...

随机推荐

  1. 如何卸载centos中自带的Java

    首先通过 Java -version 来查看是否已经安装了java 然后通过rpm -qa | grep java 来获得java的版本信息 然后再 用  rpm -e --nodeps  [这里依次 ...

  2. ADO.NET EF 4.2 中的查询缓存(避免查询缓存)

    在WinForm系统中遇到了个问题,Form1是查询窗口,根据条件查询出所有数据,双击列表后创建弹出Form2窗口编辑单个记录,但编辑后保存后,在Form2中查询到的还是旧的数据,实际数据库中已经更新 ...

  3. 项目Beta冲刺(团队6/7)

    项目Beta冲刺(团队6/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...

  4. python day- 16 面向对象

    1.类的相关知识 类:是指具有相同属性和技能的一类事物. 比如:人类 ,植物类,动物类,狗类. 对象:是类中的某一个实例,是类的具体表现. 比如:具体到某个人,某一个植物,某一条狗. class 是p ...

  5. debian配置集锦

    1 关闭蜂鸣 在/etc/bash.bashrc中加入下面的行: setterm -blength=0 2 debian bash路径显示太长 将.bashrc中的 else PS1='${debia ...

  6. 小程序登录方式切换 不做url跳转

    var filegUP = require('../../utils/getUserPassword.js'); var filemd5 = require('../../utils/md5.min. ...

  7. filter、servlet、interceptor的执行顺序

    1. Filter可认为是Servlet的一种“变种”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链.它与Servlet的区别在于:它不能 ...

  8. POJ 1737 Connected Graph(高精度+DP递推)

    题面 \(solution:\) 首先做个推销:带负数的压位高精度(加减乘+读写) 然后:由 \(N\) 个节点组成的无向图的总数为: \(2^{N*(N-1)/2}\) (也就是说这个图总共有 \( ...

  9. gradle配置

    一.你不想看到的 Gradle Build Running 话说在天朝当程序员也是很不容易的,不管是查阅资料还是下载东西,很多时候你会发现自己上网姿势不对,当然对大多数程序员来说,这都不是事儿.这次重 ...

  10. Zookeeper原理和应用

    ZooKeeper基本原理 数据模型 如上图所示,ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode.每个ZNode都可以通过其路径唯一标识, ...