题解:P9221 「TAOI-1」Pentiment

news/2025/3/10 18:55:03/文章来源:https://www.cnblogs.com/MCOIer/p/18763382

P9221 解题报告

一眼线段树优化 dp,但是调了7h。
首先考虑朴素 dp,设 \(dp_{i,j}\) 表示走到第 \(i\) 行第 \(j\) 列的方案数,转移:

\[dp_{i,j}=\sum dp_{i-1,k} \]

其中 \(k\) 表示第 \(i\) 行可以走到 \(j\) 的列。
比如如果第 \(i\) 行是下面这种情况:
qwq
\(j=3\) 时,\(2,3,4\) 都可以走到 \(j\),所以 \(dp_{i,3}=dp_{i-1,2}+dp_{i-1,3}+dp_{i-1,4}\)
同理,当 \(j=2\)\(j=4\) 时他们的 \(dp\) 值都和 \(dp_{i,3}\) 相等。
容易发现每次转移都是区间求和和区间赋值的形式,并且可以压维,那么可以考虑线段树优化。

又容易发现 \(n\leq 10^9,m\leq 10^9\)
所以一般的线段树在 \(m\) 上空间会炸,在 \(n\) 上时间会炸。
发现 \(q\) 很小,意味着有很多行都可能没有障碍。
考虑没有障碍的两行,转移时等同于全局乘 \(m\)
所以没有障碍的行可以通过快速幂来实现跳跃。
这样对线段树的调用次数就是 \(O(q)\),解决了时间问题。
使用动态开点线段树解决空间问题。
end.

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
#define N 100005
using namespace std;
inline void print(int n){if(n<0){putchar('-');print(-n);return;}if(n>9)print(n/10);putchar(n%10+'0');}
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch==EOF)return 0;if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();if(ch==EOF)break;}return x*f;}
struct point{int x,y;
}a[N];
int p[N];
struct node{int s,t,v,p,ls,rs;
}tree[3000000];
int tot,n,m,q,tot1;
unordered_map<int,vector<int> >mp;
int add(int l,int r){tree[++tot].s=l;tree[tot].t=r;tree[tot].v=tree[tot].p=tree[tot].ls=tree[tot].rs=0;return tot;
}
void push_down(int now){tree[tree[now].ls].v=tree[now].p*(tree[tree[now].ls].t-tree[tree[now].ls].s+1)%mod;tree[tree[now].ls].p=tree[now].p;tree[tree[now].rs].v=tree[now].p*(tree[tree[now].rs].t-tree[tree[now].rs].s+1)%mod;tree[tree[now].rs].p=tree[now].p;tree[now].p=0;
}
void modify(int now,int l,int r,int k){if(tree[now].s>r||tree[now].t<l)return;if(tree[now].s>=l&&tree[now].t<=r){tree[now].v=(tree[now].t-tree[now].s+1)*k%mod;tree[now].p=k;return;}int mid=(tree[now].s+tree[now].t)>>1;if(!tree[now].ls)tree[now].ls=add(tree[now].s,mid);if(!tree[now].rs)tree[now].rs=add(mid+1,tree[now].t);if(tree[now].p)push_down(now);modify(tree[now].ls,l,r,k);modify(tree[now].rs,l,r,k);tree[now].v=(tree[tree[now].ls].v+tree[tree[now].rs].v)%mod;
}
int query(int now,int l,int r){if(tree[now].t<l||tree[now].s>r)return 0;if(tree[now].s>=l&&tree[now].t<=r)return tree[now].v;int mid=(tree[now].s+tree[now].t)>>1;if(!tree[now].ls)tree[now].ls=add(tree[now].s,mid);if(!tree[now].rs)tree[now].rs=add(mid+1,tree[now].t);if(tree[now].p)push_down(now);return (query(tree[now].ls,l,r)+query(tree[now].rs,l,r))%mod;
}
int qpow(int a,int b){int res=1;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b/=2;}return res;
}
signed main(){n=read();m=read();q=read();for(int i=1;i<=q;i++){a[i].x=read();a[i].y=read();mp[a[i].x].push_back(a[i].y);}add(1,m);tree[1].v=m;tree[1].p=1;for(int i=1;i<=q;i++){if(p[tot1]!=a[i].x)p[++tot1]=a[i].x;}for(int i=1;i<=tot1;i++){if(p[i]-p[i-1]>1)modify(1,1,m,query(1,1,m)*qpow(m,p[i]-p[i-1]-2)%mod);int j=0;for(;j<mp[p[i]].size();j++){modify(1,mp[p[i]][j],mp[p[i]][j],0);if(j==0)modify(1,1,mp[p[i]][j]-1,query(1,1,mp[p[i]][j]-1));else modify(1,mp[p[i]][j-1]+1,mp[p[i]][j]-1,query(1,mp[p[i]][j-1]+1,mp[p[i]][j]-1));}if(j!=0)modify(1,mp[p[i]][j-1]+1,m,query(1,mp[p[i]][j-1]+1,m));else modify(1,1,m,query(1,1,m));}if(p[tot1]<=n-1)modify(1,1,m,query(1,1,m)*qpow(m,n-p[tot1]-1)%mod);cout<<query(1,1,m);return 0;
}

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

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

相关文章

【Java开发】Tools4AI:一个适用于企业Java应用的开源智能体框架

一、简介 GitHub主页:(https://github.com/vishalmysore/Tools4AI) Tools4AI 是一个基于 Java 的开源智能体框架,它为企业Java应用程序提供了一种集成人工智能的独特方法。作为一个大型动作模型(Large Action Model,LAM)智能体,Tools4AI 能够根据自然语言指令自主执行任务…

英语328个词缀和词根汇总(14张图)

在所有的单词记忆法中,构词法是最科学、记忆效果最佳的词汇记忆法。下面整理了高中常用的词根、词缀。利用有限的词根、词缀对英语单词进行构词分析和解形释义,单词变得好认又好记,词义也一目了然。通过构词法记单词,可以举一反三,记一识十,从而达到事半功倍的记忆效果。…

No.48 ES6---数组扩展之扩展运算符和新增方法

一、数组扩展之扩展运算符 1.扩展运算符扩展运算符(spread)是三个点(…)。将一个数组转为用逗号分隔的参数序列。<script>var arr = [10,23,45,6,7];//以前获取数组中的每个元素for(let i = 0;i<arr.length;i++){console.log(arr[i]);}//有了扩展运算符之后console.lo…

Zabbix 7.0 LTS 部署

Zabbix 7.0LTS教程 一、环境介绍 操作系统:Rocky Linux 9.5 软件版本:7.0LTS 二、安装教程 官网:Zabbix:企业级开源监控解决方案 点击右上角的下载ZABBIX选择对应的环境:选择之后往下拉会看到相应的部署步骤:2.1 软件源配置 按照文档提示:如果有epel.repo源码,需要先注释…

IDC机房无人值守:智能运维一体化解决方案

“智和网管平台”,通过实时监控、远程配置等技术实现数据中心机房的自动检测、自动报警、自动修复等功能,从而达到无需人工干预的机房运维状态,减少人为因素对设备运行的干扰,增强机房设备、设施数据的直观可视性、提高其利用率。 企业数字化转型以及5G、物联网、云…

rust学习二十.1、不安全代码之原始指针(裸指针)

一、前言 指针在前面的篇幅中已经介绍过许多,但主要是智能指针。 智能指针管理堆上的数据,并且受到rust的所有权和借用规则管理(注意,这里的所有权和借用有时候不同于最原始的那种)。 智能指针好歹能管着这些数据,但是rust中存在一些不能使用所有权管理的数据,它们需要利…

环境变量Path学习

什么是Path环境变量? “环境变量”和“path环境变量”其实是两个东西,不要混为一谈。 “环境变量”是操作系统工作环境设置的一些选项或属性参数。每个环境变量由变量名和文件路径组成的,可以设置很多个环境变量。 我们一般使用环境变量指定一个文件夹的位置,或一个应用程序…

rust学习二十.1、原始指针(裸指针)

一、前言 指针在前面的篇幅中已经介绍过许多,但主要是智能指针。 智能指针管理堆上的数据,并且受到rust的所有权和借用规则管理(注意,这里的所有权和借用有时候不同于最原始的那种)。 智能指针好歹能管着这些数据,但是rust中存在一些不能使用所有权管理的数据,它们需要利…

深度测评国产 AI 程序员,在 QwQ 和满血版 DeepSeek 助力下,哪些能力让你眼前一亮?

通义灵码上新模型选择功能,不仅引入了 DeepSeek 满血版 V3 和 R1 这两大 “新星”,Qwen2.5-Max 和 QWQ 也强势登场,正式加入通义灵码的 “豪华阵容”。开发者只需在通义灵码智能问答窗口的输入框中,单击模型选择的下拉菜单,便能轻松开启不同模型,畅享个性化服务。通义灵码…

AI Station使用笔记

一、安装maui (1)在104上,终端操作(必须有sudo权限):sudo apt install cifs-utilspip install maui==0.0.32 -i http://10.9.54.102:8888/simple --trusted-host 10.9.54.102 maui login (fang.wang03,密码为开机密码) maui project init RC_Collaboratives (前…

mysql索引浅谈

一. 索引: 索引是数据库中重要的数据结构,主要作用是提高查询的效率。索引相当于书本的目录,即可以快速定位所需数据的位置,而不用逐页查找。 二. 索引底层结构:索引底层主要采用B+树来实现索引的管理。B+树内部分为叶子节点和非叶子节点;非叶子节点主要用来存储索引和指…