P4229 某位歌姬的故事

处理复杂点的 dp 题。

思路

先考虑 \(n\) 比较小的情况,把每个询问放到线段上,发现每个格子只能满足覆盖最小的限制,于是考虑将询问有效区间排序考虑。

设 \(f[i][j]\) 表示在 \(j\) 处放最大值满足限制 \(i\),\(j\) 之前任选,\(j\) 之后不能选最大值的方案数。

\[f[i][j]=\sum_{k\in[l_{i-1},r_{i-1}]}f[i-1][k]\times val_i^{dis(r_{i-1}+1,j-1)}\times (val_i-1)^{dis(j+1,r_i)}(j\notin [l_{i-1},r_{i-1}])
\]

其中 \(dis(l,r)\) 表示 \(l,r\) 间的距离,包括 \(l,r\) 本身。

复杂度 \(O(n^2)\),可以愉快的通过 \(5\) 个测试点。

不难发现 \(n\) 特别大但 \(q\) 的个数特别小,考虑离散化。

把询问间的点离散化成一个点,询问的端点也离散化成一个点,这样一个点就代表一段区间。

同时方程中的 \(j\) 也需要改变,因为现在 \(j\) 代表一段区间,故只要区间中有至少一个点选中最大值即可。

\[f[i][j]=\sum_{k\in[l_{i-1},r_{i-1}]}f[i-1][k]\times val_i^{dis(r_{i-1}+1,j-1)}\times (val_i-1)^{dis(j+1,r_i)}\times(val_i^{len_j}-(val_i-1)^{len_j})(j\notin [l_{i-1},r_{i-1}])
\]

将方程前缀和优化,转移复杂度 \(O(1)\),总复杂度 \(O(q^2)\)。

复杂度瓶颈在离散化,使用更好的离散化方法可以做到更好的时限,不过既然能过过作者就不改了。

CODE

#include<bits/stdc++.h>
using namespace std; #define mod 998244353
#define ll long long
#define int long long const int maxm=505,maxn=2505; int n,Q,m,cntseg,cntval,cntl,cnt;
int lim[maxn],len[maxn],slen[maxn],val[maxn],tmplen[maxn],id[maxn],pos[maxn]; map<int,int>mp; ll ans;
ll f[2][maxn],sf[2][maxn],inv[maxn]; struct Qry{int l,r,h;}q[maxn],tmp[maxn]; inline void clr()
{
cnt=0,cntl=0,cntval=0,cntseg=0,ans=0;
mp.clear();
memset(f,0,sizeof(f));
memset(sf,0,sizeof(sf));
memset(inv,0,sizeof(inv));
memset(lim,0,sizeof(lim));
memset(len,0,sizeof(len));
memset(slen,0,sizeof(slen));
memset(val,0,sizeof(val));
memset(tmplen,0,sizeof(tmplen));
memset(id,0,sizeof(id));
memset(pos,0,sizeof(pos));
memset(tmp,0,sizeof(tmp));
}
inline bool cmp(Qry a,Qry b){return a.h==b.h?a.r<b.r:a.h<b.h;}
inline ll ksm(ll x,ll y)
{
ll sum=1;
for(;y;y/=2,x=x*x%mod) if(y&1) sum=sum*x%mod;
return sum;
}
inline void trans(int h)
{
if(h==1) return ;
memset(f,0,sizeof(f));memset(sf,0,sizeof(f));
sf[1][0]=f[1][0]=inv[0]=1;
for(int i=1;i<=cntl;i++) sf[1][i]=sf[1][i-1],slen[i]=slen[i-1]+tmplen[i],inv[i]=ksm(ksm(h-1,slen[i]),mod-2);
tmp[0].r=0;
for(int i=1;i<=cnt;i++)
{
swap(f[1],f[0]);swap(sf[0],sf[1]);
for(int j=0;j<=tmp[i].l-1;j++) f[1][j]=sf[1][j]=0;
for(int j=tmp[i].l;j<=tmp[i].r;j++)
{
f[1][j]=f[0][j];
if(j>tmp[i-1].r)
{
f[1][j]+=ksm(h-1,slen[tmp[i-1].r])*
ksm(h,slen[j-1]-slen[tmp[i-1].r])%mod*
sf[0][tmp[i-1].r]%mod*(ksm(h,tmplen[j])-ksm(h-1,tmplen[j])+mod)%mod;
f[1][j]%=mod;
}
sf[1][j]=(sf[1][j-1]+f[1][j]*inv[j]%mod)%mod;
}
for(int j=tmp[i].r+1;j<=cntl;j++) sf[1][j]=sf[1][j-1],f[1][j]=0;
}
ans=ans*sf[1][cntl]%mod*ksm(h-1,slen[cntl])%mod;
} signed main()
{
// freopen("1.in","r",stdin);
int _;
scanf("%lld",&_);
while(_--)
{
clr();
scanf("%lld%lld%lld",&n,&Q,&m);
cntseg=0;
for(int i=1;i<=Q;i++)
{
scanf("%lld%lld%lld",&q[i].l,&q[i].r,&q[i].h);
mp[q[i].l]=1,mp[q[i].r]=1;val[i]=q[i].h;
}
sort(q+1,q+Q+1,cmp);
mp[1]=1,mp[n]=1;
auto it1=mp.begin(),it2=mp.begin();
for(it2++;it2!=mp.end();it2++,it1++) it2->second+=it1->second;
for(it1=mp.begin(),it2=mp.begin(),it2++;it1!=mp.end();it2++,it1++)
{
id[++cntseg]=it1->first;len[cntseg]=1;
if(it2!=mp.end()&&it2->first>it1->first+1) id[++cntseg]=it1->first+1,len[cntseg]=it2->first-it1->first-1;
}
bool flg=false;
for(int i=1;i<=Q;i++)
{
q[i].l=lower_bound(id+1,id+cntseg+1,q[i].l)-id;
q[i].r=lower_bound(id+1,id+cntseg+1,q[i].r)-id;
int l=q[i].l,r=q[i].r;
int mx=0;bool has=0;
for(int j=l;j<=r;j++)
{
if(!lim[j]) lim[j]=q[i].h,has=1;
else mx=max(mx,lim[j]);
}
if(!has&&mx<q[i].h) flg=1;
}
if(flg) {puts("0");continue;}
sort(val+1,val+Q+1);cntval=unique(val+1,val+Q+1)-val-1;
int i=1;ans=1;
for(int j=1;j<=cntval;j++)
{
cntl=0,cnt=0;
while(i<=Q&&q[i].h==val[j]) tmp[++cnt]=q[i++];
for(int k=1;k<=cntseg;k++) if(lim[k]==val[j]) tmplen[pos[k]=++cntl]=len[k];
for(int k=1;k<=cnt;k++)
{
for(;lim[tmp[k].l]!=val[j];tmp[k].l++);
for(;lim[tmp[k].r]!=val[j];tmp[k].r--);
tmp[k].l=pos[tmp[k].l],tmp[k].r=pos[tmp[k].r];
}
trans(val[j]);
}
for(int i=1;i<=cntseg;i++)
if(!lim[i]) ans=ans*ksm(m,len[i])%mod;
printf("%lld\n",ans);
}
}

P4229 某位歌姬的故事的更多相关文章

  1. 题解-洛谷P4229 某位歌姬的故事

    题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...

  2. Loj #2331. 「清华集训 2017」某位歌姬的故事

    Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...

  3. UOJ#346. 【清华集训2017】某位歌姬的故事 动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ346.html 题解 首先按照 $m_i$ 的大小排个序. 如果某一个区间和一个 m 值比他小的区间有交,那么显然可以将这 ...

  4. Week Three

    2018.12.10 1.[BZOJ 4818][P 3702] 2.[AGC007 A] 3.[AGC007 B] 4.[AGC007 C] 5.[AGC007 D] 2018.12.11 1.[B ...

  5. 关于cpu体系架构的一些有趣的故事分享

    从排查一次匪夷所思的coredump,引出各种体系架构的差异. 本文中的所有内容来自学习DCC888的学习笔记或者自己理解的整理,如需转载请注明出处.周荣华@燧原科技 1 背景 从全世界有记载的第一台 ...

  6. Offer是否具有法律效力?

    版权声明:原创作品,同意转载,转载时请务必以超链接形式标明文章原始出版.作者信息和本声明.否则将追究法律责任.本文地址: http://blog.csdn.net/jobchanceleo/archi ...

  7. 单身福利来了:VR恋人为你量身定制一个女朋友

    相对于传统视频体验,VR视频给人带来了更加真实的体验.特别是对于单身狗来说,能在VR中拥有一个虚拟的恋人可谓是莫大的心灵安慰.近日,上海微雁文化传媒有限公司正式发布了首款养成类手机应用VR恋人. VR ...

  8. Asp.Net 常用工具类之加密——对称加密DES算法(2)

    又到周末,下午博客园看了两篇文章,关于老跳和老赵的程序员生涯,不禁感叹漫漫程序路,何去何从兮! 转眼毕业的第三个年头,去过苏州,跑过上海,从一开始的凌云壮志,去年背起行囊默默回到了长沙准备买房,也想有 ...

  9. BFC基础分析

    W3C官方对于BFC的描述只有3小段,强烈建议想理解BFC的朋友先去看看,链接见文末. 常见的文档流分为:定位流.浮动流.普通流3种.BFC是普通流中的一种. 本文提出3个问题并给出使用BFC来解决这 ...

  10. JSJ—编译器与虚拟机哪个重要?

    阅读本文约“2分钟” 熟悉Java的朋友都知道虚拟机还有编译器,那么它们各自主要的功能是什么?谁比较重要呢?让我们来了解一下这两位美女的故事. 虚拟机可以说就是Java,她能让程序运行起来. 但是编译 ...

随机推荐

  1. 使用go+gin编写日志中间,实现自动化收集http访问信息,错误信息等,自动化生成日志文件

    1.首先在logger包下 点击查看代码 package logger import ( "fmt" "io" "net/http" &qu ...

  2. android java.lang.Exception: java.net.ProtocolException: Expected HTTP 101 response

    Android stomp长连接连接异常: 报错:java.lang.Exception: java.net.ProtocolException: Expected HTTP 101 response ...

  3. 每天5分钟复习OpenStack(十五)Ceph与Bcache结合

    上一章我们成功部署了bcache,这一章我们将Ceph与Bcache结合来使用,使用Bcache来为ceph的数据盘提速. 1 ceph 架构 一个标准的ceph集群可能是如下的架构,SSD/NVME ...

  4. 总结篇4:redis 核心数据存储结构及核心业务模型实现应用场景

    总结篇4:redis 核心数据存储结构及核心业务模型实现应用场景 redis 和memcached 有什么区别?为什么在高并发下,单线程的redis 比多线程的效率高? mc 可以缓存图片和视频,re ...

  5. 《Effective TypeScript》条款21 - 类型扩展

    本文主要通过一些实际的代码示例,来帮助大家理解什么是类型扩展,本文主要内容如下: 什么是类型扩展 代码示例 总结 什么是类型扩展? TypeScript 需要从你指定的单一值中决定一组可能的值,这个过 ...

  6. CSS – RWD (Responsive Web Design) 概念篇

    介绍 Only PC 以前是没有手机的, 只有电脑, 所以做开发, 只需要开发电脑版本就可以了. Mobile Version 后来手机诞生, 有钱的公司就做两个版本, 一个手机版, 一个电脑版. 没 ...

  7. Nuxt Kit 组件管理:注册与自动导入

    title: Nuxt Kit 组件管理:注册与自动导入 date: 2024/9/15 updated: 2024/9/15 author: cmdragon excerpt: Nuxt Kit 为 ...

  8. C++ STL queue容器——队列

    queue容器 基本概念 queue是一种**先进先出的数据结构,它有两个出口,queue容器允许从一端新增元素,从另一端移除元素. queue容器没有迭代器,所有元素进出都必须符合"先进先 ...

  9. Blazor与IdentityServer4的集成

    本文合并整理自 CSDN博主「65号腕」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. Blazor与IdentityServer4的集成(一) IdentityS ...

  10. Linux内存管理2.6 -反向映射RMAP(最终版本)

    所谓反向映射是相对于从虚拟地址到物理地址的映射,反向映射是从物理页面到虚拟地址空间VMA的反向映射. RMAP能否实现的基础是通过struct anon_vma.struct anon_vma_cha ...