首页 > 其他分享 >P4229 某位歌姬的故事 题解

P4229 某位歌姬的故事 题解

时间:2024-10-17 21:45:25浏览次数:6  
标签:__ P4229 int 题解 歌姬 tot tc ml 最大值

P4229 某位歌姬的故事 题解

\(n\le 9\times 10^8\),显然复杂度不与 \(n\) 相关。\(m\le 500\),显然可以接受 \(O(Tm^2)\) 的做法。对于 \([l,r]\),考虑套路地将端点离散化,使得复杂度只和关键点个数有关。考虑对于 \([l,r,m]\),离散化后被分成了 \(a_1,a_2,\cdots,a_p\) 段,那么这些段的最大值是好预处理的,且一定不会超过 \(m\),且其中至少会有一个取到段中的最大值 \(m\),于是发现对于一个最大值为 \(m\) 的区间如果在之前被放过一定取到了最大值为 \(m\) 的区间的最大值,那么设 \(dp_{i,j}\) 表示前 \(i\) 个段,最后 选择最大值 \(m\) 的位置是 \(j\),则将 \(m\) 相同的分到一类,每次寻找前一个和其 \(m\) 相同的来转移即可。

代码的实现是较为繁琐的。

#include <bits/stdc++.h>
#define N 1005
#define int long long
#define mod 998244353
#define __(a) memset(a, 0, sizeof a)
using namespace std;
int T;
int n, q, A;
int ml[N], mr[N], mh[N];
int b[N << 1], tot;
int c[N], tc;
int mn[N];

int qpow(int x, int y) {
	int ans = 1;
	while (y) {
		if (y & 1)
			ans = ans * x % mod;
		x = x * x % mod;
		y >>= 1;
	}
	return ans;
}
int dp[N][N];
int pr[N];
void clr() {
	__(dp);
	__(ml);
	__(mr);
	__(mh);
	__(pr);
	__(b);
	__(c);
	tot = tc = 0;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> T;
	while (T--) {
		clr();
		cin >> n >> q >> A;
		for (int i = 1; i <= q; i++) {
			cin >> ml[i] >> mr[i] >> mh[i];
			--ml[i];
			b[++tot] = ml[i];
			b[++tot] = mr[i];
			c[++tc] = mh[i];
		}
		b[++tot] = 0, b[++tot] = n;
		sort(b + 1, b + 1 + tot);
		tot = unique(b + 1, b + 1 + tot) - b - 1;
		sort(c + 1, c + 1 + tc);
		tc = unique(c + 1, c + 1 + tc) - c - 1;
		for (int i = 1; i <= tot; i++)
			mn[i] = A + 1;
		for (int i = 1; i <= q; i++) {
			ml[i] = lower_bound(b + 1, b + 1 + tot, ml[i]) - b + 1;
			mr[i] = lower_bound(b + 1, b + 1 + tot, mr[i]) - b;
			for (int j = ml[i]; j <= mr[i]; j++) 
				mn[j] = min(mn[j], mh[i]);
		}
		int ans = 1;
		for (int i = 2; i <= tot; i++) 
			if (mn[i] > A)
				ans = ans * qpow(A, b[i] - b[i - 1]) % mod;
		int fg = 0;
		for (int i = 1; i <= q; i++) {
			while (ml[i] <= mr[i] && mn[mr[i]] < mh[i])
				--mr[i];
			if (ml[i] > mr[i]) {
				cout << "0\n";
				fg = 1;
				break;
			}
			pr[mr[i]] = max(pr[mr[i]], ml[i]);
		}
		if (fg)
			continue;
		for (int i = 1; i <= tc; i++) {
			int lst = 1;
			dp[1][1] = 1;
			for (int j = 2; j <= tot; j++)
				if (mn[j] == c[i]) {
					memset(dp[j], 0, sizeof dp[j]);
					int tmp = qpow(c[i] - 1, b[j] - b[j - 1]);
					for (int k = pr[j]; k <= lst; k++)
						dp[j][k] = dp[lst][k] * tmp % mod;
					for (int k = 1; k <= lst; k++)
						dp[j][j] = (dp[j][j] + dp[lst][k]) % mod;
					dp[j][j] = dp[j][j] * ((qpow(c[i], b[j] - b[j - 1]) - tmp + mod) % mod) % mod;
					lst = j;
				}
			int as = 0;
			for (int j = 1; j <= lst; j++)
				as = (as + dp[lst][j]) % mod;
			ans = ans * as % mod;
		}
		cout << ans << "\n";
	}
	return 0;
} 

标签:__,P4229,int,题解,歌姬,tot,tc,ml,最大值
From: https://www.cnblogs.com/Rock-N-Roll/p/18473173

相关文章

  • ZZJC新生训练赛第四场题解
    ZZJCACM新生训练赛-2024.10.16题目难度Easy(简单):B,C,D,GMedium(中等):A,EAnti-AK(防AK):EC题解题思路A页既可以是彩印也可以是黑白印,B页只能是彩印,所以只要比较A页彩印和A页黑白印的价格高低就好。因为a,b,x,y最大都是1e9,用int直接相乘的话会爆掉,所以......
  • DMA连续发送多帧但是只有最后一帧数据发出问题解决方法
    问题描述DMA连续发送多帧但是只有最后一帧数据发出原因分析DMA发送未完成时,下次DMA请求启动,导致之前的数据被放弃传输了解决办法创建DMA发送缓冲区,当启动DMA请求的时候,检测DMA设备是不是正在忙,如果正在忙,就把数据放入发送缓冲区等待,上次DMA发送完成的时会产生DMA发送完......
  • 【学校训练记录】10月个人训练赛3个人题解
    A:根据题意我们可知,第一种事件为从1到i的和,第二种事件为从y到i的和故我们可以通过前缀和来保存从i到i+1所化的时间。再遍历寻找最小值即可#include<bits/stdc++.h>#defineendl"\n"#defineintlonglongusingnamespacestd;intn,a[1010];voidsolve(){ cin>>n;......
  • 题解:GZOI2024 D2T2 乒乓球
    考场上切了,但是比较神奇的题,应该是蓝/紫。Discription乒乓球\(\text{}\)时间限制:\(\bold{3}\)秒众所周知,一场乒乓球比赛共有两个玩家\(A\)和\(B\)参与,其中一场比赛由多局比赛组成,而每局比赛中又由多盘比赛组成。每盘比赛\(A\)或\(B\)只有一名选手获胜。当其中一名......
  • [题解]P1311 [NOIP2011 提高组] 选择客栈
    P1311[NOIP2011提高组]选择客栈P6032选择客栈加强版只要\([l,r]\)区间之内存在一个\(i\)使得\(w[i]\lep\),这个区间就是符合条件的。所以我们遍历每一个元素\(i\),根据贪心的思想我们维护\([1,i]\)区间内满足\(w[i]\lep\)的最大\(i\),记为\(mp\)。对于每个元素\(i\),寻找\(......
  • 【题解】twt studio2024 萌新欢乐赛
    迟来的题解本文更新到个人主页中,后续如果有任何修正变动也只会在网页端更新~特别鸣谢小羽毛在羽猫球一题的题解:)感谢兴航学弟在T3的题解。比赛链接:https://www.luogu.com.cn/contest/196515T1签到题,所有参与选手均满分。略。T2https://www.luogu.com.cn/article/37n1idam......
  • P9731 [CEOI2023] Balance 题解
    首先考虑\(S=2\)怎么做,我们把它转化为图论问题。对于每一行的两个点的颜色连一条无向边,那我们相当于要给这些边定向。最后要求\(|in_u-out_u|\le1\)。会发现这个要求很像欧拉回路。但是欧拉回路是要求每个点的入度和出度相等,怎么办呢?我们再建一个超级源点,向每个奇数度数的点......
  • 常见ElasticSearch 面试题解析(上)
    前言ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulweb接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。ElasticSearch用于云计算中,能够达到实时搜索,稳定,可靠,......
  • 2024-10-17每日一题题解
    最大子段和题目描述给出一个长度为\(n\)的序列\(a\),选出其中连续且非空的一段使得这段和最大。样例输入72-43-12-43样例输出4题解tips:无脑暴力法:枚举每一段区间,再对每一段区间求和,时间复杂度为\(O(n^3)\),会超时(n为1e5,则应该在\(O(nlogn)\)的时间范围内)......
  • 【题解】【记忆化递归】——Function
    【题解】【记忆化递归】——FunctionFunction题目描述输入格式输出格式输入输出样例输入#1输出#1提示数据规模与约定1.思路解析2.AC代码Function通往洛谷的传送门题目描述对于一个递归函数w......