HDU 5145 分块 莫队
给定n个数,q个询问[l,r]区间,每次询问该区间的全排列多少种。
数值都是30000规模
首先考虑计算全排列,由于有同种元素存在,相当于每次在len=r-l+1长度的空格随意放入某种元素即$\binom{len}{k_1}$,那么下种元素即为$\binom{len-k_1}{k2}$,以此类推,直至最后直接填满,那么全排列为${\frac{len!}{k_1!k_2!…k_n!}}$
然后可以发现可以直接O(1)求得左右相邻区间的值(就是乘或除),那么考虑分块莫队。
/** @Date : 2017-09-23 18:57:10
* @FileName: HDU 5145 分块 莫队.cpp
* @Platform: Windows
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version : $Id$
*/
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std; const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8;
const LL mod = 1e9 + 7; int k[30010];
int a[30010];
int blc[30010];
LL fac[30010];
LL inv[30010];
LL res[30010];
struct yuu
{
LL l, r;
int m;
}b[30010]; int cmp(yuu a, yuu b)
{
if(blc[a.l] != blc[b.l])
return a.l < b.l;
return a.r < b.r;
} void init()
{
fac[0] = fac[1] = 1;
inv[0] = inv[1] = 1;
for(LL i = 2; i <= 30005; i++)
{
fac[i] = (fac[i - 1] * i % mod + mod) % mod;
inv[i] = (mod - mod / i) * inv[mod % i] % mod;
}
}
int main()
{
init();
int T;
cin >> T;
while(T--)
{
LL n, q;
scanf("%lld%lld", &n, &q);
int sqr = sqrt(1.0 * n);
for(int i = 1; i <= n; i++)
scanf("%d", a + i), blc[i] = (i - 1) / sqr + 1;
for(int i = 1; i <= q; i++)
{
scanf("%lld%lld", &b[i].l, &b[i].r);
b[i].m = i;
}
sort(b + 1, b + 1 + q, cmp);
MMF(k);
LL l = 1, r = 0;
LL ans = 1, cnt = 0;
for(int i = 1; i <= q; i++)
{
while(r < b[i].r)
{
r++;
k[a[r]]++;
cnt++;
ans = (ans * cnt % mod * inv[k[a[r]]] % mod + mod) % mod;
}
while(l > b[i].l)
{
l--;
cnt++;
k[a[l]]++;
ans = (ans * cnt % mod * inv[k[a[l]]] % mod + mod) % mod;
}
while(r > b[i].r)
{
ans = (ans * inv[cnt] % mod * k[a[r]] % mod + mod) % mod;
cnt--;
k[a[r]]--;
r--;
}
while(l < b[i].l)
{
ans = (ans * inv[cnt] % mod * k[a[l]] % mod + mod) % mod;
cnt--;
k[a[l]]--;
l++;
}
while(ans < 0)
ans += mod;
res[b[i].m] = ans;
}
for(int i = 1; i <= q; i++)
printf("%lld\n", res[i]);
}
return 0;
}
HDU 5145 分块 莫队的更多相关文章
- 【BZOJ-3809】Gty的二逼妹子序列 分块 + 莫队算法
3809: Gty的二逼妹子序列 Time Limit: 80 Sec Memory Limit: 28 MBSubmit: 1072 Solved: 292[Submit][Status][Di ...
- 2018.11.07 NOIP训练 L的鞋子(权值分块+莫队)
传送门 乱搞题. 我直接对权值分块+莫队水过了. 不过调了30min30min30min发现ststst表挂了是真的不想说什么233. 代码
- bzoj 3585 mex - 线段树 - 分块 - 莫队算法
Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问 ...
- 【BZOJ2038】【2009国家集训队】小Z的袜子(hose) 分块+莫队
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...
- BZOJ.3809.Gty的二逼妹子序列(分块 莫队)
题目链接 /* 25832 kb 26964 ms 莫队+树状数组:增加/删除/查询 都是O(logn)的,总时间复杂度O(m*sqrt(n)*logn),卡不过 莫队+分块:这样查询虽然变成了sqr ...
- 分块+莫队||BZOJ3339||BZOJ3585||Luogu4137||Rmq Problem / mex
题面:P4137 Rmq Problem / mex 题解:先莫队排序一波,然后对权值进行分块,找出第一个没有填满的块,直接for一遍找答案. 除了bzoj3339以外,另外两道题Ai范围都是1e9. ...
- 【BZOJ 2120】数颜色【分块/莫队】
题意 给出n个数字和m个操作.操作有两种.1:查询区间[l,r]内不同种类得数字个数.2: 将下标为p得数字修改为v 分析 如果不是修改操作的话,用莫队贼简单就可以水过,但是因为带了修改就有一些麻烦了 ...
- P4396 [AHOI2013]作业 分块+莫队
这个题正解是莫队+树状数组,但是我个人非常不喜欢树状数组这种东西,所以决定用分块来水这个题.直接在莫队维护信息的时候,维护单点同时维护块内信息就行了. 莫队就是这几行核心代码: void add(in ...
- BZOJ 3585: mex(分块+莫队)
传送门 解题思路 首先直接莫队是能被卡的,时间复杂度不对.就考虑按照值域先进行分块再进行莫队,然后统计答案的时候就暴力扫所有的块,直到一个块内元素不满,再暴力扫这个块就行了,时间复杂度O(msqrt( ...
随机推荐
- C语言自评
问卷调查:你对自己的未来有什么规划?做了哪些准备?答:做设计方面的工作:正在努力自学有关这方面的知识 你认为什么是学习?学习有什么用?现在学习动力如何?为什么?答:学习就是增长见识:学习的作用就是为了 ...
- Jmeter 快速入门--简单的http压测
1.添加线程组 打开jmeter主窗口后,选择左侧树形结构里的"测试计划",然后右键选择添加,选择"threads(users)",选择"线程组&qu ...
- 【Linux 命令】- find 命令
find 是日常工具箱中功能更强大.更灵活的命令行工具之一,因此值得花费更多的时间. 最简单的,find 跟上路径寻找一些东西.例如: find / 它将找到(并打印出)系统中的每个文件.而且由于一切 ...
- 更新user的方法
from django.contrib.auth.admin import UserAdmin from django.contrib.auth.forms import UserChangeForm ...
- Linux 下定位java应用 cpu高的原因(转)
使用场景: 遇到Linux下java应用cpu占用很高的时候,我们很想知道此时的应用到底在做什么导致资源的消耗. 方便我们进一步定位和优化~ 1.查询cpu耗用top5的进程(你也可以top10) [ ...
- BZOJ 1975 魔法猪学院(A*求K短路)
显然每次贪心的走最少消耗的路径即可.那么也就是找出最短路,次短路,,,K短路之后消耗E的能量的最多的路径条数. 也就是裸的A*算法. #include <bits/stdc++.h> us ...
- P4551 最长异或路径
题目描述 给定一棵 nnn 个点的带权树,结点下标从 111 开始到 NNN .寻找树中找两个结点,求最长的异或路径. 异或路径指的是指两个结点之间唯一路径上的所有边权的异或. 输入输出格式 输入格式 ...
- 聊聊flink的Async I/O
// This example implements the asynchronous request and callback with Futures that have the // inter ...
- 【转】大数据分析(Big Data OLAP)引擎Dremel, Tenzing 以及Impala
引自:http://blog.csdn.net/xhanfriend/article/details/8434896 对于数据分析师来说,SQL是主要的语言. Hive为Hadoop提供了支持SQL运 ...
- Unity3D for VR 学习(3): 暴风魔镜PC Input小改造–自己动手、丰衣足食
在做手游的时候,80%时间是在PC调试的,例如业务逻辑.AI算法.核心玩法等. 拿到魔镜提供的demo,晕了,必须得安装到Android机器上,才能调试,究其原因,有三: 需要用到手机陀螺仪 需要用到 ...