P11164 [BalkanOI 2023] Permutations

news/2025/10/3 22:20:02/文章来源:https://www.cnblogs.com/Tmbcan/p/19125095

思路

先判断是否有解。
即判断区间是否存在三元组 \((p_i,p_j,p_k)(i < j < k)\) 使得 \(p_i > p_j > p_k\);或者二元组 \((p_i,p_j)(i<j)\) 使得 \(p_i > p_j > \min_{k=1}^{L-1} \min_{k=R+1}^{n} \space p_k\)
贪心的覆盖区间,三元组对于 \(j\) 我们只找最靠右的 \(i\) 和最靠左的 \(k\);二元组对 \(j\) 只找最靠右的 \(i\)。扫描线一遍 \(j\),把权值都挂在 \(i\) 上维护即可。

然后求方案数。
先考虑一个弱化问题:将 \(1\sim n\) 的排列 \(P_n\) 放成最长递减子序列长度至多为二,共有多少种方案。
考虑一种类似维护连续段的转移,把序列按点 \((i,p_i)\) 摊到平面上,称 \(p_{i-1} > p_i < p_{i+1}\) 为一个“谷”。
\(f_{i,j}\) 表示放完前 \(i\) 个数,最后一个“谷”在 \(j\) 的方案数。
发现我们新插入数只能是使最后一个“谷”向右移动,或者拼接在段的右端点上,即 \(f_{i,j}\) 会贡献给 \(\sum_{k=j}^{i+1} f_{i+1,k}\)
在转移状态的平面上看这个方程,发现我们转移的路径是每次从当前层先到下一层,到下一层后可以选择向右转移若干状态或者不动。把这件事看成网格图上走路,每次必须向上走一步,然后可以选择向右走一些格子。每次选择是否向右走,以及向右走几格,对应方案与从 \((1,1)\) 走到 \((n+1,n+1)\) 的路径相对应。当 \(j>i\) 时状态无意义,即不能越过直线 \(y = x\)

回到原问题。
\(mx = \max_{i=L}^{R} \space p_i\)。小于 \(mx\) 的数一定按升序放,而剩下的大于 \(mx\) 的数在小于 \(mx\) 的数放完前需要升序放。
这与我们刚才在网格图上走路的方式很像。
\(Len = R-L+1\),考虑共剩下 \(n-Len\) 个数,其中小于 \(mx\) 的有 \(mx-Len\) 个,大于 \(mx\) 的数有 \(n-mx\) 个。
然后像网格图上走路一样刻画放数的过程,走的步数与大于和小于 \(mx\) 的数的个数向对应。即相当于从 \((mx,Len)\) 走到 \((n,n)\) 不越过 \(y=x\)
\(y=x+1\) 对称,反射容斥一下,答案为 \(C_{2n-mx-Len}^{n-Len} - C_{2n-mx-Len}^{n-Len+1}\)

代码

const int N = 3e5+10,INF = 0x3f3f3f3f;
const ll mod = 1e9+7;
int n,m,a[N];
ll ans[N];
struct G1{int l,r,id;inline int operator < (const G1&G){if(r^G.r) return r < G.r;return l < G.l;}
}g1[N];
struct G2{int l;
}g2[N];
struct Query{int l,r,id;inline int operator < (const Query&G) const{if(r^G.r) return r < G.r;return l < G.l;}
}q[N];
int st[N],stop;
struct Tree1{int minn[N<<2],maxn[N<<2];Tree1(){memset(minn,0x3f,sizeof(minn));}inline void build(int p,int nl,int nr){if(nl==nr){minn[p] = maxn[p] = a[nl];return ;}int mid = (nl+nr) >> 1;build(p<<1,nl,mid);build(p<<1|1,mid+1,nr);minn[p] = Min(minn[p<<1],minn[p<<1|1]);maxn[p] = Max(maxn[p<<1],maxn[p<<1|1]);}inline int query_min(int p,int nl,int nr,int ql,int qr){if(ql>qr) return INF;if(ql<=nl && nr<=qr) return minn[p];int mid = (nl+nr) >> 1;int res = INF;if(ql<=mid) res = Min(res,query_min(p<<1,nl,mid,ql,qr));if(qr>mid) res = Min(res,query_min(p<<1|1,mid+1,nr,ql,qr));return res;}inline int query_max(int p,int nl,int nr,int ql,int qr){if(ql>qr) return 0;if(ql<=nl && nr<=qr) return maxn[p];int mid = (nl+nr) >> 1;int res = 0;if(ql<=mid) res = Max(res,query_max(p<<1,nl,mid,ql,qr));if(qr>mid) res = Max(res,query_max(p<<1|1,mid+1,nr,ql,qr));return res;}
}t1;
struct Tree2{int vis[N<<2],maxn[N<<2];inline void update_vis(int p,int nl,int nr,int x){if(nl==nr){vis[p] = 1;return ;}int mid = (nl+nr) >> 1;if(x<=mid) update_vis(p<<1,nl,mid,x);else update_vis(p<<1|1,mid+1,nr,x);vis[p] = vis[p<<1]|vis[p<<1|1];}inline int query_vis(int p,int nl,int nr,int ql,int qr){if(ql>qr) return 0;if(ql<=nl && nr<=qr) return vis[p];int mid = (nl+nr) >> 1;int res = 0;if(ql<=mid) res = query_vis(p<<1,nl,mid,ql,qr);if(res) return res;if(qr>mid) res = query_vis(p<<1|1,mid+1,nr,ql,qr);return res;}inline void update_max(int p,int nl,int nr,int x,int k){if(nl==nr){maxn[p] = Max(maxn[p],k);return ;}int mid = (nl+nr) >> 1;if(x<=mid) update_max(p<<1,nl,mid,x,k);else update_max(p<<1|1,mid+1,nr,x,k);maxn[p] = Max(maxn[p<<1],maxn[p<<1|1]);}inline int query_max(int p,int nl,int nr,int ql,int qr){if(ql>qr) return 0;if(ql<=nl && nr<=qr) return maxn[p];int mid = (nl+nr) >> 1;int res = 0;if(ql<=mid) res = Max(res,query_max(p<<1,nl,mid,ql,qr));if(qr>mid) res = Max(res,query_max(p<<1|1,mid+1,nr,ql,qr));return res;}
}t2;
ll mul[N<<1],inv[N<<1];
inline ll quick_pow(ll x,ll y){ll res = 1;while(y){if(y&1) (res *= x)%=mod;(x *= x)%=mod;y >>= 1;}return res;
}
inline ll H(int maxn,int len){int ta = n-len;int tb = n-maxn-1;return (mul[ta+tb+1]*(ta-tb)%mod*inv[tb+1]%mod*inv[ta+1]%mod+mod)%mod;
}
int main(){// freopen("in.in","r",stdin);// freopen("out.out","w",stdout);read(n);mul[0] = 1;for(int i=1;i<=n+n;++i) mul[i] = mul[i-1]*i%mod;inv[n+n] = quick_pow(mul[n+n],mod-2);for(int i=n+n;i;--i) inv[i-1] = inv[i]*i%mod;for(int i=1;i<=n;++i){read(a[i]);g1[i].id = i;}t1.build(1,1,n);for(int i=1;i<=n;++i){while(stop && a[i]>a[st[stop]]) --stop;g1[i].l = st[stop];st[++stop] = i;}stop = 0;for(int i=n;i;--i){while(stop && a[i]<a[st[stop]]) --stop;g1[i].r = st[stop];st[++stop] = i;}stop = 0;for(int i=1;i<=n;++i){while(stop && a[i]>a[st[stop]]) --stop;g2[i].l = st[stop];st[++stop] = i;}read(m);for(int i=1;i<=m;++i){read(q[i].l,q[i].r);q[i].id = i;}sort(g1+1,g1+1+n);sort(q+1,q+1+m);for(int i=1,nowq=1,nowg1=1;i<=n && nowq<=m;++i){while(g1[nowg1].r<=i && nowg1<=n){if(g1[nowg1].l && g1[nowg1].r) t2.update_vis(1,1,n,g1[nowg1].l);++nowg1;}if(g2[i].l) t2.update_max(1,1,n,g2[i].l,a[i]);while(q[nowq].r<=i && nowq<=m){if(!t2.query_vis(1,1,n,q[nowq].l,q[nowq].r)){if(t2.query_max(1,1,n,q[nowq].l,q[nowq].r)<Min(t1.query_min(1,1,n,1,q[nowq].l-1),t1.query_min(1,1,n,q[nowq].r+1,n)))ans[q[nowq].id] = H(t1.query_max(1,1,n,q[nowq].l,q[nowq].r),i-q[nowq].l+1);}++nowq;}}for(int i=1;i<=m;++i) printf("%lld\n",ans[i]);// fclose(stdin);// fclose(stdout);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/926386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

旅游电子商务的三创赛网站建设英文seo推广

本文将详细介绍如何在Spring Boot应用程序中实现邮件发送服务。我们将探讨Spring Boot集成邮件发送服务的基本概念&#xff0c;以及如何使用Spring Boot和第三方邮件服务提供商来实现邮件发送。此外&#xff0c;我们将通过具体的示例来展示如何在Spring Boot中配置和使用邮件发…

Spring事务管理:-rollbackFor

rollbackFor属性用于控制出现何种异常类型,回滚事务。(默认情况下,只有出现RuntimeException才会回滚) 如: @Transactional(rollbackFor = {Exception.class}) @Override public void save(Emp emp) {//1.保存员工…

在JavaScript / HTML中,动态计算调整文字大小 - 详解

在JavaScript / HTML中,动态计算调整文字大小 - 详解2025-10-03 22:09 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; di…

微信图片批量保存的办法

微信聊天的图片有时候想要批量保存,但又不想一张一张取点,所以请看此文章已经给官方提建议了,目前还没在最新版看到相关功能。 解决办法:python 脚本(通过pywinauto 控制点击下一张和下载按钮,然后通过判断文件夹…

网站运营专员具体每天怎么做网站建设收费标准报价

ps&#xff1a; 为啥不用蒲公英了&#xff0c;就是因为有广告了&#xff0c;获取个UDID还安装游戏&#xff0c;真恶心?&#xff0c;所以找了新的获取UDID都方法&#xff0c;网页直接获取就可以&#xff0c;不会安装软件。 UDID 是一种 iOS 设备的特殊识别码。除序号之外&…

详细介绍:使用 C# 设置 Excel 单元格数据验证

详细介绍:使用 C# 设置 Excel 单元格数据验证pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

乐清人才网官方网站深圳建网站公司哪家好

原理图&#xff1a; 矩阵按键原理图&#xff1a; 实验板接口原理图&#xff1a; 得到对应图&#xff1a; 扫描按键原理&#xff1a; 按键的COLUMN1、2、3分别制0&#xff0c;每次只允许其中一个为0其他都是1&#xff08;POW1和POW2正常状况为上拉&#xff09;&#xff0c;当有…

博客园实验1

1 // 打印一个字符小人 2 #include <stdio.h> 3 int main() 4 { 5 printf(" O \n"); 6 printf("<H>\n"); 7 printf("I I\n"); 8 return 0; 9 }View Code1 …

做盗版系统网站会不会php app网站建设

本书目录&#xff1a;点击进入 一、总结内容 二、习题 2.1 【选择题】以下Vue指令中&#xff0c;哪些指令具备简写方式&#xff1f; 2.2 【编程题】以下Vue指令中&#xff0c;哪些指令具备简写方式&#xff1f; &#xff1e; 效果 &#xff1e; 代码 一、总结内容 了解核…

arm汇编

寄存器 R0–R3 传参/返回值 R4–R11 局部变量(callee 保存) R12 临时 R13 SP 栈指针 R14 LR 返回地址 R15 PC 程序计数器 CPSR 标志位:N Z C V 常用指令 MOV Rd, #imm 立即数传送 ADD/ADC…

腾度网站建设品牌营销模式

前段时间&#xff0c;家里的iPad被家人误操作&#xff0c;导致iPad变成不可使用状态。自己折腾了半天&#xff0c;没有找到解决办法。没有办法&#xff0c;只好拿到手机维修店去修理,很快就修理好了.其实也很简单--就是对iPad进行了刷机操作。当然我也看到了刷机的方法。今天&a…

模型与分词器

当我们说“让AI理解人类语言”时,第一步是什么? 计算机是无法直接处理文本的,它需要数字。而模型与分词器就是完成“文本 → 数字 → 理解”这个神奇转换的关键二人组。本文将带你彻底理解这两者是什么、如何工作以…

云锵投资 2025 年 9 月简报

季报摘要本季度,量化基金策略业绩:15.48%,中,全国排名:8672/13200;平均 Beta:1.00; 本季度,量化股票策略业绩:25.05%,良,全国排名:4926/13200;平均 Beta:1.61; 本季度,量化期权策略业绩:21.71%(中性…

subclipse最新版本更新地址

subclipse最新版本更新地址 https://gitcode.com/gh_mirrors/upda/updates/tree/main/subclipse

详细介绍:C++与Open CASCADE中的STEP格式处理:从基础到高级实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

板子2

最近经常跑到以前代码里复制的东西,其实简单。 其中逆序对甚至vp的时候开始写了个挂的,和将军手搓了半天。 干脆放这里备用。 【模版】逆序对 【模版】笛卡尔树

简单网站开发项目实例企业网址是怎么写的

提起SimpleDateFormat类&#xff0c;想必做过Java开发的童鞋都不会感到陌生。没错&#xff0c;它就是Java中提供的日期时间的转化类。这里&#xff0c; 为什么说SimpleDateFormat类有线程安全问题呢&#xff1f;有些小伙伴可能会提出疑问&#xff1a;我们生产环境上一直在使用S…

网站搭建多少钱徐州百都网络非常好网站建设代码怎么导入图片

我一直不知道我在大家心目中的定位是什么&#xff0c;但我内心其实是把自己定义为一个『工具人』的。可能是因为我自己本身就是程序员&#xff0c;所以更能理解程序员的不易吧。所以&#xff0c;我尽量不写水文&#xff0c;只分享干货。就是希望大家看了能够有所收获&#xff0…

从DQN到Double DQN:分离动作选择与价值评估,解决强化学习中的Q值过估计问题

2015年DQN在Atari游戏上取得突破性进展,从此以后强化学习终于能处理复杂环境了,但没多久研究者就注意到一些奇怪的现象: Q值会莫名其妙地增长到很大,智能体变得异常自信,坚信某些动作价值极高。实际跑起来却发现这…

P9877/QOJ5069 Vacation

题意 给定长度为 \(n\) 的序列 \(a\) 和定值 \(c\),\(q\) 次操作,每次操作可以是单点修改,也可以是查询 \([l,r]\) 的所有区间长度 \(\le c\) 的子区间中区间和最大是多少。 \(c\le n\le 2\times10^5,q\le 5\times1…