[ZOJ3899]State Reversing
[ZOJ3899]State Reversing
试题描述
Yakumo Yukari is with no doubt one of the most powerful youkai in Gensokyo. Her ability is manipulating boundaries. She has \(N\) unknown creatures called "sinsack" or "the crime bag" which live in the basement of Yukari's house. Sinsacks are numbered from \(1\) to \(N\). There are \(M\) rooms with infinite capacity in the basement and each room has two states: available or unavailable. Yukari will reverse the state of consecutive rooms every day. Sinsacks can only live in available rooms. And each available room should contain at least one sinsack.
As a 17-year-old girl, recently Yukari is interested in how many different ways to arrange sinsacks in rooms. At the beginning, all rooms are available. In the following \(D\) days, Yukari will ask you the number of ways after reversing. Two ways \(A\) and \(B\) are regarded as the same if for any room in \(A\), there exists a room in \(B\) that the sinsacks in these two rooms have the same set of numbers. In other words, rooms are indistinguishable.
现有 \(N\) 只不同的怪兽,和 \(M\) 个相同的从 \(1\) 到 \(M\) 编号的房间,每个房间有空闲和不空闲两种状态,怪兽只能住进处于空闲状态的房间,房间容量无穷。现在给出 \(D\) 个操作,每次操作翻转一个区间 \([l_i, r_i]\) 内的房间的状态,求每次操作后分配怪兽的方案数(注意房间相同的意思是交换一个分配方案中的两个房间不算产生一个新的方案)。
所有答案均要对 \(880803841\) 取模。
输入
The first line of the input contains an integer \(T\) (\(T \le 10\)), indicating the number of cases. For each test case:
The first line contains three integers \(N\), \(M\) and \(D\) (\(1 \le M \le N\), \(D \le 100000\)). Their meanings are described above.
The following \(D\) lines each contain two integers \(l\) and \(r\) (\(1 \le l \le r \le M\)) denoting the consecutive rooms \(l, l + 1, \cdots , r\) which are reversed by Yukari on that day.
输出
For each query, output the number of different ways to arrange sinsacks. The answer should modulo \(880803841\) for it can be very large.
输入示例
2
3 3 2
2 2
1 3
5 5 3
1 3
2 2
1 5
输出示例
3
1
15
25
15
数据规模及约定
见“输入”
题解
这就是一个裸的第二类斯特林数,然后再强行加一个线段树。
第二类斯特林数 \(S(n, m)\) 表示将 \(n\) 个物品分成 \(m\) 个集合的方案数。如果暴力 \(O(n^2)\) dp 显然有 \(S(n, m) = S(n-1, m-1) + S(n-1, m) \cdot m\),但是要想快速求 \(S(n, 1) \sim S(n, n)\),就用不上这个 dp 了。
考虑 \(S(n, m)\) 的组合意义有
\]
翻译一下就是将 \(n\) 个不同的物品放入 \(k\) 个不同的篮子中,可以有篮子是空的。那么这个东西其实可以先枚举有 \(m\) 个篮子非空,然后分三步完成:从 \(k\) 个篮子中取出 \(m\) 个篮子,\(m\) 个篮子排一个顺序,将 \(n\) 个物品放入 \(m\) 个篮子中,然后乘法原理即可得到上式。
然后二项式反演可得
S(n, k) = \sum_{m=0}^k \frac{(-1)^{k-m}}{(k-m)!} \cdot \frac{m^n}{m!}
\]
于是成了一个卷积的形式。
至于那个区间操作用线段树维护应该没啥好讲的吧。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std;
#define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
#define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
#define maxn 262144
#define MOD 880803841
#define Groot 26
#define LL long long
int Pow(int a, int b) {
int ans = 1, t = a;
while(b) {
if(b & 1) ans = (LL)ans * t % MOD;
t = (LL)t * t % MOD; b >>= 1;
}
return ans;
}
int brev[maxn];
void FFT(int *a, int len, int tp) {
int n = (1 << len);
rep(i, 0, n - 1) if(i < brev[i]) swap(a[i], a[brev[i]]);
rep(i, 1, len) {
int wn = Pow(Groot, MOD - 1 >> i);
if(tp < 0) wn = Pow(wn, MOD - 2);
for(int j = 0; j < n; j += 1 << i) {
int w = 1;
rep(k, 0, (1 << i >> 1) - 1) {
int la = a[j+k], ra = (LL)w * a[j+k+(1<<i>>1)] % MOD;
a[j+k] = (la + ra) % MOD;
a[j+k+(1<<i>>1)] = (la - ra + MOD) % MOD;
w = (LL)w * wn % MOD;
}
}
}
if(tp < 0) {
int invn = Pow(n, MOD - 2);
rep(i, 0, n - 1) a[i] = (LL)a[i] * invn % MOD;
}
return ;
}
void Mul(int *A, int *B, int n, int m) {
int N = 1, len = 0;
while(N <= n + m) N <<= 1, len++;
rep(i, 0, N - 1) brev[i] = (brev[i>>1] >> 1) | ((i & 1) << len >> 1);
rep(i, n + 1, N - 1) A[i] = 0;
rep(i, m + 1, N - 1) B[i] = 0;
FFT(A, len, 1); FFT(B, len, 1);
rep(i, 0, N - 1) A[i] = (LL)A[i] * B[i] % MOD;
FFT(A, len, -1);
return ;
}
int ava[maxn<<2];
bool tag[maxn<<2];
void build(int o, int l, int r) {
tag[o] = 0;
if(l == r) ava[o] = 1;
else {
int mid = l + r >> 1, lc = o << 1, rc = lc | 1;
build(lc, l, mid); build(rc, mid + 1, r);
ava[o] = ava[lc] + ava[rc];
}
return ;
}
void pushdown(int o, int l, int r) {
if(l == r || !tag[o]) return (void)(tag[o] = 0);
int mid = l + r >> 1, lc = o << 1, rc = lc | 1;
tag[lc] ^= 1; ava[lc] = mid - l + 1 - ava[lc];
tag[rc] ^= 1; ava[rc] = r - mid - ava[rc];
tag[o] = 0;
return ;
}
void rev(int o, int l, int r, int ql, int qr) {
pushdown(o, l, r);
if(ql <= l && r <= qr) tag[o] ^= 1, ava[o] = r - l + 1 - ava[o];
else {
int mid = l + r >> 1, lc = o << 1, rc = lc | 1;
if(ql <= mid) rev(lc, l, mid, ql, qr);
if(qr > mid) rev(rc, mid + 1, r, ql, qr);
ava[o] = ava[lc] + ava[rc];
}
return ;
}
int ifac[maxn], A[maxn], B[maxn];
void work() {
int n = read(), m = read(), q = read();
ifac[1] = 1;
rep(i, 2, n) ifac[i] = (LL)(MOD - MOD / i) * ifac[MOD%i] % MOD;
ifac[0] = 1;
rep(i, 1, n) ifac[i] = (LL)ifac[i-1] * ifac[i] % MOD;
rep(i, 0, n) {
A[i] = (LL)Pow(i, n) * ifac[i] % MOD;
B[i] = ifac[i]; if(i & 1) B[i] = MOD - B[i];
}
Mul(A, B, n, n);
build(1, 1, m);
while(q--) {
int l = read(), r = read();
rev(1, 1, m, l, r);
printf("%d\n", A[ava[1]]);
}
return ;
}
int main() {
int T = read();
while(T--) work();
return 0;
}
[ZOJ3899]State Reversing的更多相关文章
- ZOJ3899 State Reversing 【线段树 + NTT】
题目链接 ZOJ3899 题解 比较累,做一道水题 还被卡常= = 我在\(ZOJ\)交过的两道\(NTT\)都被卡常了.. 哦,题意就是求第二类斯特林数,然后线段树维护一下集合数量就可以了 #inc ...
- 【ZOJ3899】State Reversing 解题报告
[ZOJ3899]State Reversing Description 有\(N\)个不同的怪兽,编号从\(1\) 到\(N\).Yukari有\(M\)个相同的房间,编号为\(1\)到\(M\). ...
- 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查。。。
异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Ser ...
- react+redux教程(五)异步、单一state树结构、componentWillReceiveProps
今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...
- 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)
说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对“状态模式”并不陌生,因为我们之前使用到了状态模式进行重构.上一篇博客我们 ...
- 2015年软件测试STATE报告
STATE OF TESTING 2015 Report 测试职业的地理位置分配 大部分有5年以上工作经验 大部分是Test Leader 测试工程师角色 测试工程师怎么工作的? 测试中的软件 ...
- React Native props & state
今天又敲了一丁点代码,看了一下props和state的用法 原本以为state只是一个状态,但是又阅读了一下原文,才知道state是一组状态,这些状态是开发者自己定义的,都统一在state这个大类底下 ...
- React Native知识11-Props(属性)与State(状态)
一:Props(属性) 大多数组件在创建时就可以使用各种参数来进行定制.用于定制的这些参数就称为props(属性).props是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变 通过 ...
- Neural Pathways of Interaction Mediating the Central Control of Autonomic Bodily State 自主神经系统-大脑调节神经通路
Figure above: Critchley H D, Harrison N A. Visceral influences on brain and behavior[J]. Neuron, 201 ...
随机推荐
- java对象中的三种状态和脏检查及刷新缓存机制
瞬时状态 瞬时状态又称临时状态.如果java对象与数据库中的数据没有任何的关联,即此java对象在数据库中没有相关联的记录,此时java对象的状态为瞬时状态,session对于 瞬时状态的ava对象是 ...
- React学习(4)——向服务器请求数据并显示
本文中涉及到的技术包括:node.js/express服务器的搭建.fetch发送数据请求. 在之前的几篇文章中,介绍了如何搭建基础的React项目,以及一些简单知识,现在,我们还需要掌握如何用Rea ...
- Vue+webpack构建一个项目
1.安装CLI命令的工具 推荐用淘宝的镜像 npm install -g @vue/cli @vue/cli-init 2.使用命令构建一个名为myapp的项目 vue init webpack m ...
- 糖果 南阳acm589
糖果 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 topcoder工作室的PIAOYIi超级爱吃糖果,现在他拥有一大堆不同种类的糖果,他准备一口气把它们吃完,可是 ...
- 对bluebird的理解
前言 Promise:把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数. 在公众号的开发里面用的const Promise = require('bluebird');con ...
- Python3 模块、包调用&路径
''' 以下代码均为讲解,不能实际操作 ''' ''' 博客园 Infi_chu ''' ''' 模块的优点: 1.高可维护性 2.可以大大减少编写的代码量 模块一共有三种: 1.Python标准库 ...
- 关于xampp 集成开发包电脑重启mysql无法启动的问题
关于xampp 集成开发包电脑重启mysql无法启动的问题. 在做php开发时,安装过xampp,也不知道是版本老了还是什么问题,总是出现当天晚上下班关机,第二天上班mysql不能启动,在网上查找些资 ...
- 初步学习pg_control文件之十一
接前文 初步学习pg_control文件之十,再看这个 XLogRecPtr prevCheckPoint; /* previous check point record ptr */ 发生了che ...
- scidb
貌似是给科学家用的数据库,暂不研究
- Android Studio引入AAR文件
一.编译生成AAR文件 二.把AAR文件复制到项目的libs目录下 三.在项目的配置文件中加入如下代码: android { //other code repositories{ flatDir{ d ...