Loj #2331. 「清华集训 2017」某位歌姬的故事
Loj #2331. 「清华集训 2017」某位歌姬的故事
IA 是一名会唱歌的女孩子。
IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿。这首歌一共有 \(n\) 个音符,第 \(i\) 个音符的音高为 \(h_i\)。IA 的音域是 \(A\),她只能唱出 \(1\sim A\) 中的正整数音高。因此 \(1\le h_i\le A\)。
在写歌之前,IA 需要确定下这首歌的结构,于是她写下了 \(Q\) 条限制,其中第 \(i\) 条为:编号在 \(l_i\) 到 \(r_i\) 之间的音符的最高音高为 \(m_i\)。在确定了结构之后,她就可以开始写歌了。不过她还是想知道,一共有多少种可能的歌曲满足她的所有限制?她听说你还有 9 个月就要去 IOI 了,于是希望你帮她计算一下这个值。
输入格式
从标准输入读入数据。
输入的第一行包含一个整数 \(T(T\le 20)\),代表测试数据的组数。
每组数据的第一行包含三个正整数 \(n,Q,A\)。接下来 \(Q\) 行,每行三个整数 \(l_i,r_i,m_i\),表示一条限制。保证 \(1\le l_i\le r_i\le n, 1\le m_i\le A\)。
输出格式
输出到标准输出。
输出文件只有一行,表示可能的歌曲数目。这个数可能很大,请将答案模 \(998244353\) 输出。
数据范围与提示
$n \leq 9\times 10^8 $ $Q \leq 500 $ $A \leq 9\times 10^8 $
首先我们将坐标离散化。也就是对于所有区间\([l,r]\),我们将\(l,l+1,r,r+1\)离散。
然后将所有询问按\(m_i\)排序。我们发现当询问\(i\)与询问\(j\)的区间有交,如果\(m_i<m_j\),那么交的部分全部分配给\(i\)。这样,\(m\)不同的区间就没有交了。
接着考虑做法。因为我们可以很容易算出区间最大值\(\leq\)某个值的答案,所以考虑容斥。我们设\(f_{S}\)表示\(\{S\}\)集合中的询问都不满足的答案。如果要求不满足询问\((l,r,m)\),那么区间\([l,r]\)内的元素要\(\leq m-1\)。最终答案就是:
\]
我们发现,如果所有区间的\(m\)不同,那么很好做,因为即使降低了某些询问的上限,也不会改变相交区间的分配情况。于是对于\(m\)相同的情况,我们考虑\(DP\)
我们将\(m\)相同的询问按左端点排序,设\(f_{i,j}\)表示满足了\(DP\)了前\(i\)个询问,降低了上限的询问中最右端点为\(j\)的答案。考虑加入第\(i\)个询问的时候就与\(j\)判断一下就知道\(i\)还可以控制的区间有多少了。\(DP\)的时候还要带着容斥系数\(DP\)。
代码:
#include<bits/stdc++.h>
#define ll long long
#define Q 505
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
const ll mod=998244353;
ll ksm(ll t,ll x) {
ll ans=1;
for(;x;x>>=1,t=t*t%mod)
if(x&1) ans=ans*t%mod;
return ans;
}
int T;
int n,q,A;
vector<int>disc;
int len[Q<<2];
int tot;
struct query {
int l,r,mx;
bool operator <(const query &a)const {
if(mx!=a.mx) return mx<a.mx;
if(l!=a.l) return l<a.l;
return r<a.r;
}
bool operator ==(const query &a)const {
return l==a.l&&r==a.r&&mx==a.mx;
}
}s[Q];
int tag[Q<<2];
int pre[Q<<2];
ll f[Q<<2][Q<<2];
ll DP(int L,int R) {
pre[0]=0;
for(int i=1;i<tot;i++)
pre[i]=pre[i-1]+(tag[i]?0:len[i]);
ll inv=ksm(s[L].mx,mod-2)*(s[L].mx-1)%mod;
f[L][0]=1;
f[L][s[L].r]=(mod-ksm(inv,pre[s[L].r]-pre[s[L].l-1]))%mod;
for(int i=L+1;i<=R;i++) {
for(int j=0;j<tot;j++) {
if(!f[i-1][j]) continue ;
(f[i][j]+=f[i-1][j])%=mod;
int New=0;
if(s[i].r>j) New=pre[s[i].r]-pre[max(j,s[i].l-1)];
(f[i][max(s[i].r,j)]+=(mod-1)*f[i-1][j]%mod*ksm(inv,New))%=mod;
}
}
ll ans=0;
for(int i=0;i<tot;i++) (ans+=f[R][i])%=mod;
return ans;
}
int main() {
T=Get();
while(T--) {
memset(f,0,sizeof(f));
disc.clear();
n=Get(),q=Get(),A=Get();
for(int i=1;i<=q;i++) {
s[i].l=Get(),s[i].r=Get(),s[i].mx=Get();
disc.push_back(s[i].l);
disc.push_back(s[i].r);
}
disc.push_back(0);
disc.push_back(1);
disc.push_back(n);
sort(disc.begin(),disc.end());
for(int i=0,x=disc.size();i<x;i++)
if(disc[i]+1<=n) disc.push_back(disc[i]+1);
sort(disc.begin(),disc.end());
disc.resize(unique(disc.begin(),disc.end())-disc.begin());
tot=disc.size();
for(int i=0;i<tot;i++)
if(i<tot-1) len[i]=disc[i+1]-disc[i];
else len[i]=1;
for(int i=1;i<=q;i++) {
s[i].l=lower_bound(disc.begin(),disc.end(),s[i].l)-disc.begin();
s[i].r=lower_bound(disc.begin(),disc.end(),s[i].r)-disc.begin();
}
sort(s+1,s+1+q);
q=unique(s+1,s+1+q)-s-1;
memset(tag,0,sizeof(tag));
ll ans=1;
for(int i=1;i<=q;i++) {
int j=i;
while(j<q&&s[j+1].mx==s[i].mx) j++;
ll tem=DP(i,j)%mod;
int sum=0;
for(int k=i;k<=j;k++) {
for(int p=s[k].l;p<=s[k].r;p++) {
if(!tag[p]) sum+=len[p];
tag[p]=1;
}
}
ans=ans*tem%mod*ksm(s[i].mx,sum)%mod;
i=j;
}
for(int i=1;i<tot;i++) if(!tag[i]) ans=ans*ksm(A,len[i])%mod;
cout<<ans<<"\n";
}
return 0;
}
Loj #2331. 「清华集训 2017」某位歌姬的故事的更多相关文章
- Loj #2324. 「清华集训 2017」小 Y 和二叉树
Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...
- Loj #2321. 「清华集训 2017」无限之环
Loj #2321. 「清华集训 2017」无限之环 曾经有一款流行的游戏,叫做 *Infinity Loop***,先来简单的介绍一下这个游戏: 游戏在一个 \(n \times m\) 的网格状棋 ...
- Loj 2320.「清华集训 2017」生成树计数
Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...
- [LOJ#2330]「清华集训 2017」榕树之心
[LOJ#2330]「清华集训 2017」榕树之心 试题描述 深秋.冷风吹散了最后一丝夏日的暑气,也吹落了榕树脚下灌木丛的叶子.相识数年的Evan和Lyra再次回到了小时候见面的茂盛榕树之下.小溪依旧 ...
- [LOJ#2329]「清华集训 2017」我的生命已如风中残烛
[LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...
- [LOJ#2328]「清华集训 2017」避难所
[LOJ#2328]「清华集训 2017」避难所 试题描述 "B君啊,你当年的伙伴都不在北京了,为什么你还在北京呢?" "大概是因为出了一些事故吧,否则这道题就不叫避难所 ...
- [LOJ#2327]「清华集训 2017」福若格斯
[LOJ#2327]「清华集训 2017」福若格斯 试题描述 小d是4xx9小游戏高手. 有一天,小d发现了一个很经典的小游戏:跳青蛙. 游戏在一个 \(5\) 个格子的棋盘上进行.在游戏的一开始,最 ...
- [LOJ#2326]「清华集训 2017」简单数据结构
[LOJ#2326]「清华集训 2017」简单数据结构 试题描述 参加完IOI2018之后就是姚班面试.而你,由于讨厌物理.并且想成为乔布斯一样的创业家,被成功踢回贵系. 转眼,时间的指针被指向201 ...
- [LOJ#2324]「清华集训 2017」小Y和二叉树
[LOJ#2324]「清华集训 2017」小Y和二叉树 试题描述 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙 ...
随机推荐
- 不一样的 SQL Server 日期格式化
不一样的 SQL Server 日期格式化 Intro 最近统计一些数据,需要按天/按小时/按分钟来统计,涉及到一些日期的格式化,网上看了一些文章大部分都是使用 CONVERT 来转换的,SQL Se ...
- 【Python实践-1】求一元二次方程的两个解
知识点: import sys, sys模块包含了与Python解释器和它的环境有关的函数. “sys”是“system”的缩写.sys.exit() 中途退出程序, (注:0是正常退出,其他为不正常 ...
- 【机器学习】--EM算法从初识到应用
一.前述 Em算法是解决数学公式的一个算法,是一种无监督的学习. EM算法是一种解决存在隐含变量优化问题的有效方法.EM算法是期望极大(Expectation Maximization)算法的简称,E ...
- javaScript设计模式--观察者模式(observer)
观察者模式(observer):又被称为 发布-订阅者模式或者消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能耦合. 一.这样的需求 在实现自己的需求,而添加一些功能代码,但是又不想新添加 ...
- Elasticsearch倒排索引结构
一切设计都是为了提高搜索的性能 倒排索引(Inverted Index)也叫反向索引,有反向索引必有正向索引.通俗地来讲,正向索引是通过key找value,反向索引则是通过value找key. 先来回 ...
- Linux+.Net Core+Nginx(在Linux上使用Nginx反向代理.Net Core 项目)
Linux+.Net Core+Nginx 之前的文章中有提到关于使用Nginx在linux来实现反向代理,今天我们继续加点料.在Centos7中部署.NetCore,然后使用Nginx进行反向代理! ...
- 微服务实战(三):落地微服务架构到直销系统(构建基于RabbitMq的消息总线)
从前面文章可以看出,消息总线是EDA(事件驱动架构)与微服务架构的核心部件,没有消息总线,就无法很好的实现微服务之间的解耦与通讯.通常我们可以利用现有成熟的消息代理产品或云平台提供的消息服务来构建自己 ...
- 【Android Studio安装部署系列】六、在模拟器上运行项目
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 在模拟器上运行项目的步骤.不过在实际开发中,一般不采用这种方式,因为影响电脑的运行,所以一般使用真机运行项目. 运行项目 创建模拟器 ...
- DSAPI 图形图像篇(上)
彩色文字对象 基于一些特殊需求,本人开发了彩色文字对象,该功能通过类似html代码的方式指示文本,并输出图像. 我们还是先来看一张图像. 这不是文本,是通过指定文本代码输出的图像.我们来看一下实现代码 ...
- Git 安装配置手册
Git 安装配置手册 首先我们要了解 Git 是类似于 SVN 用来管理项目的 首先要先下载 Git ,这个东西相当于一个核,是该功能的核心 下载地址(<https://gitforwindow ...