Solution -「多校联训」神
\(\mathcal{Description}\)
Link.
给定 \(n\) 阶排列 \(a\),\(q\) 次询问,每次给出 \(1\le l_1\le r_1<l_2\le r_2\le n\) 且 \(r_1-l_1=r_2-l_2\),询问满足 \(\forall j\in[1,r_1-l_1+1],~a_{j+l_1-1}<a_{b_j+l_2-1}\) 的 \((r_1-l_1+1)\) 阶排列 \(b\) 的个数,模 \((10^9+7)\)。
多测,\(\sum n,\sum q\le10^5\),\(a\) 的逆序对数 \(\le10^5\)。
\(\mathcal{Solution}\)
暴力做法:设前后询问区间为 \(A\) 和 \(B\),把两个区间的元素丢一起升序排序,则每个 \(A\) 中元素选择匹配点的方案数为其后方 \(B\) 类元素个数减去 \(A\) 类元素个数。
将同属一类的连续元素视为一段,那么有结论:段数为 \(\mathcal O(\sqrt n)\) 级别。
每个 \(B\) 段与后方所有 \(A\) 段组成逆序对,故段数与逆序对数是平方关系,而逆序对数是 \(\mathcal O(n)\) 级别,故段数 \(\mathcal O(\sqrt n)\) 级别。
利用主席数查找前驱快速求出每段长度,即可 \(\mathcal O(n\log n+q\sqrt n\log n)\) 求解。
\(\mathcal{Code}\)
/*~Rainybunny~*/
#include <cstdio>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
const int MAXN = 1e5, MOD = 1e9 + 7;
int n, q, root[MAXN + 5], fac[MAXN + 5], ifac[MAXN + 5];
inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
inline int mul( const long long a, const int b ) { return int( a * b % MOD ); }
inline int add( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
inline int mpow( int a, int b ) {
int ret = 1;
for ( ; b; a = mul( a, a ), b >>= 1 ) ret = mul( ret, b & 1 ? a : 1 );
return ret;
}
inline void init() {
fac[0] = 1;
rep ( i, 1, MAXN ) fac[i] = mul( i, fac[i - 1] );
ifac[MAXN] = mpow( fac[MAXN], MOD - 2 );
per ( i, MAXN - 1, 0 ) ifac[i] = mul( i + 1, ifac[i + 1] );
}
struct SegmentTree {
static const int MAXND = 2e6;
int node, ch[MAXND][2], sum[MAXND];
inline void insert( int& u, const int l, const int r, const int x ) {
int v = u, mid = l + r >> 1; u = ++node;
ch[u][0] = ch[v][0], ch[u][1] = ch[v][1], sum[u] = sum[v] + 1;
if ( l == r ) return ;
if ( x <= mid ) insert( ch[u][0], l, mid, x );
else insert( ch[u][1], mid + 1, r, x );
}
inline int count( const int u, const int v, const int l, const int r,
const int ql, const int qr ) {
if ( !v ) return 0;
if ( ql <= l && r <= qr ) return sum[v] - sum[u];
int mid = l + r >> 1, ret = 0;
if ( ql <= mid ) ret += count( ch[u][0], ch[v][0], l, mid, ql, qr );
if ( mid < qr ) ret += count( ch[u][1], ch[v][1], mid + 1, r, ql, qr );
return ret;
}
inline int prefix( const int u, const int v, const int l, const int r,
const int x ) {
if ( !x || sum[v] <= sum[u] ) return 0;
if ( l == r ) return l;
int mid = l + r >> 1;
if ( x <= mid ) return prefix( ch[u][0], ch[v][0], l, mid, x );
if ( int t = prefix( ch[u][1], ch[v][1], mid + 1, r, x ); t ) return t;
return prefix( ch[u][0], ch[v][0], l, mid, x );
}
} sgt;
int main() {
freopen( "god.in", "r", stdin );
freopen( "god.out", "w", stdout );
int T; init();
for ( scanf( "%d", &T ); T--; sgt.node = 0 ) {
scanf( "%d %d", &n, &q );
rep ( i, 1, n ) {
int t; scanf( "%d", &t );
sgt.insert( root[i] = root[i - 1], 1, n, t );
}
for ( int l1, r1, l2, r2; q--; ) {
scanf( "%d %d %d %d", &l1, &r1, &l2, &r2 );
int rt1[] = { root[l1 - 1], root[r1] },
rt2[] = { root[l2 - 1], root[r2] };
int mxl = sgt.prefix( rt1[0], rt1[1], 1, n, n ),
mxr = sgt.prefix( rt2[0], rt2[1], 1, n, n ), cnt = 0, ans = 1;
while ( mxl || mxr ) {
if ( mxl < mxr ) {
int lef = sgt.prefix( rt1[0], rt1[1], 1, n, mxr ),
len = sgt.count( rt2[0], rt2[1], 1, n, lef, mxr );
cnt += len;
mxr = sgt.prefix( rt2[0], rt2[1], 1, n, lef );
} else {
int lef = sgt.prefix( rt2[0], rt2[1], 1, n, mxl ),
len = sgt.count( rt1[0], rt1[1], 1, n, lef, mxl );
if ( cnt < len ) { ans = 0; break; }
ans = mul( ans, mul( fac[cnt], ifac[cnt - len] ) );
cnt -= len;
mxl = sgt.prefix( rt1[0], rt1[1], 1, n, lef );
}
}
printf( "%d\n", ans );
}
}
return 0;
}
Solution -「多校联训」神的更多相关文章
- Solution -「多校联训」最小点覆盖
\(\mathcal{Description}\) Link. 求含有 \(n\) 个结点的所有有标号简单无向图中,最小点覆盖为 \(m\) 的图的数量的奇偶性.\(T\) 组数据. \( ...
- Solution -「多校联训」排水系统
\(\mathcal{Description}\) Link. 在 NOIP 2020 A 的基础上,每条边赋权值 \(a_i\),随机恰好一条边断掉,第 \(i\) 条段的概率正比于 \(a ...
- Solution -「多校联训」I Love Random
\(\mathcal{Description}\) 给定排列 \(\{p_n\}\),可以在其上进行若干次操作,每次选取 \([l,r]\),把其中所有元素变为原区间最小值,求能够得到的所有不同序 ...
- Solution -「多校联训」签到题
\(\mathcal{Description}\) Link. 给定二分图 \(G=(X\cup Y,E)\),求对于边的一个染色 \(f:E\rightarrow\{1,2,\dots,c\ ...
- Solution -「多校联训」朝鲜时蔬
\(\mathcal{Description}\) Link. 破案了,朝鲜时蔬 = 超现实树!(指写得像那什么一样的题面. 对于整数集 \(X\),定义其 好子集 为满足 \(Y\sub ...
- Solution -「多校联训」消失的运算符
\(\mathcal{Description}\) Link. 给定长度为 \(n\) 的合法表达式序列 \(s\),其中数字仅有一位正数,运算符仅有 - 作为占位.求将其中恰好 \(k\) ...
- Solution -「多校联训」假人
\(\mathcal{Description}\) Link. 一种物品有 长度 和 权值 两种属性,现给定 \(n\) 组物品,第 \(i\) 组有 \(k_i\) 个,分别为 \((1,a ...
- Solution -「多校联训」古老的序列问题
\(\mathcal{Description}\) Link. 给定序列 \(\{a_n\}\),和 \(q\) 次形如 \([L,R]\) 的询问,每次回答 \[\sum_{[l,r]\su ...
- Solution -「多校联训」Sample
\(\mathcal{Description}\) Link (稍作简化:)对于变量 \(p_{1..n}\),满足 \(p_i\in[0,1],~\sum p_i=1\) 时,求 \(\ma ...
随机推荐
- Cookie.Session到Token和JWT
一.session和cookie: 现在一般都是session和cookie一起用,一起提.但是他们俩其实不是一定要在一起. session的产生原因是,http协议是无状态的 这就导致了,不同的用户 ...
- Win10编辑Host文件授权问题
今天重温Kafka命令, 使用KafkaTool连接Broker,需要修改主机名,发现host修改时,提示以下错误: C:\Windows\System32\drivers\etc\hosts.txt ...
- leetcode 33. 搜索旋转排序数组 及 81. 搜索旋转排序数组 II
33. 搜索旋转排序数组 问题描述 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定 ...
- 使用Redis分布式锁控制请求串行处理
1.需求背景 在一些写接口的场景下,由于一些网络因素导致用户的表单重复提交,就会在相邻很短的时间内,发出多个数据一样的请求.后台接口的幂等性保证一般都是先检查数据的状态,然后决定是否进行执行写入操作, ...
- 如何通俗地理解docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...
- 什么是VPC
1 什么是私有网络(VPC) 私有网络是一块可用户自定义的网络空间,您可以在私有网络内部署云主机.负载均衡.数据库.Nosql快存储等云服务资源.您可自由划分网段.制定路由策略.私有网络可以配置公网网 ...
- python 求模运算符--判断奇偶数
#!/usr/bin/python #coding=utf-8 #好好学习,天天向上 number = input("please enter a number:") number ...
- python30day
内容回顾 tcp协议的多人多次通信 和一个人通信多说句话 和一个人聊完再和其他人聊 bind 绑定一个id和端口 socket()tcp协议的server listen 监听,代表socket服务的开 ...
- python 小兵(4)之文件操作 小问题
1.光标不对就用seek 2.文件操作方面注意不要变修改变删除,会爆出文件正在运行不能操作 3.w模式下只有开始打开的时候会清空 4.文件操作的时候用as 后面的参数进行操作,不能用文件名进行操作 5 ...
- Python打印JSON中中文的解决办法
code #!/usr/bin/python # encoding=utf-8 import json data = [{"a": "中文"}] print j ...