[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 ...
随机推荐
- 其他乱七八糟的css
white-space:normal; word-break:break-all;字母数字强制换行表格宽度失效给上table-layout:fixed(display: table-cell;此元素会 ...
- linux下SVN CVS命令大全
1.将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如:svn checkout svn: // 192.168. 1.1 / pro / doma ...
- HyperLedger Fabric 1.4 架构(6.2)
6.2.1 架构演进 Fabric架构经历了0.6版本到1.0版本的演进,架构上进行了重大改进,从0.6版本的结构简单演进到可扩展.多通道的设计,在架构上有了质的飞跃:从1.0版本以后,架 ...
- 匈牙利算法模板 hdu 1150 Machine Schedule(二分匹配)
二分图:https://blog.csdn.net/c20180630/article/details/70175814 https://blog.csdn.net/flynn_curry/artic ...
- TensorFlow深层神经网络常用方法
深度学习所示深层神经网络的代名词,重要特性:多层.非线性. 若只通过线性变换,任意层的神经网络模型与单层神经网络模型的表达能力没有任何区别,这是线性模型的局限性.对于线性可分的问题中,线性模型可解决, ...
- LeetCode:26. Remove Duplicates from Sorted Array(Easy)
1. 原题链接 https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/ 2. 题目要求 给定一个已 ...
- ionic 入口禁止加载其他页面
.state('memberOrders', { prefetchTemplate: false, url: '/memberOrders', templateUrl: '/MemberOrders' ...
- Ubuntu下使用Git_3
这里是我举得小白阶段比较困难的地方了, 当在我们向远程数据库推送数据之前,有其他用户向远程数据库推送的相同的文件的时候,服务器会拒绝我们的推送,这个时候就需要我们来整合这两个文件 如图说是,现在显示的 ...
- python 网络编程(socketserver,阻塞,其他方法)
重点回顾: (重点)粘包 : 就是因为接收端不知道如何接收数据,造成接收数据的混乱的问题 只发生在tcp协议上. 因为tcp协议的特点是面向数据流形式的传输 粘包的发生主要是因为tcp协议有两个机制: ...
- 树莓派的WIFI配置
参考网址: http://www.cnblogs.com/iusmile/archive/2013/03/30/2991139.html http://my.oschina.net/pikeman/b ...