首页 > 其他分享 >CF466D Increase Sequence

CF466D Increase Sequence

时间:2024-01-07 16:33:40浏览次数:26  
标签:CF466D cnt 题意 Sequence int memset long Increase 序列

题意

给定一个序列 \(a\),每次操作可以将区间 \([l, r]\) 中的所有元素加一,要求最后使所有元素等于 \(h\)。

要求:

  1. 任意两个区间的左右端点互不重合(\(l1 \neq l2\) 且 \(r1 \neq r2\));
  2. 对 \(10^9 + 7\) 取模。

思路

首先,可以考虑预处理出一个新的序列,表示出原数列中每个数与 \(h\) 的差,这样可以节约一定的时间复杂度。这里约定 \(c_i = a_i - a_{i - 1}\),将问题转换为了如何使序列 \(c\) 全部归零。

现在考虑 \(c_i\) 可能的几种情况:

  • \(c_i > 1\):无解。由于每个区间最多选一次,如果 \(c_i > 1\),这意味着 \(i\) 处需要大于一次被选择,不符合题意。
  • \(c_i = 1\):此时一定有一个起始点 \(l\) 在 \(i\) 处。这里我们维护一个 \(cnt\),表示 \(l\) 的个数。那么在此时,\(cnt\) 加一。
  • \(c_i = -1\):此时需要在 \(i\) 处在设置一个 \(r\),所以需要和前面的某个 \(l\) 匹配,故将答案乘以 \(cnt\),再将 \(cnt\) 减一。
  • \(c_i = 0\):这时考虑几种情况:
  1. \(i\) 处其实什么都没有;
  2. \(i\) 处同时作为一个 \(l\) 和一个 \(r\)。那么就需要对当前位置的 \(l\) 进行匹配,将答案乘上 \(cnt + 1\)。

代码

友情提示:一定要开 long long

#include <bits/stdc++.h>
#define int long  long
using namespace std;
const int mod = 1e9 + 7, N = 2005;
int a[N], b[N];
int n, h, cnt = 0, ans = 1;
signed main() {
	while (~scanf("%lld%lld", &n, &h)) {
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		for (int i = 1; i <= n; i++) {
			scanf("%lld", &a[i]);
			a[i] = h - a[i];
		}
		for (int i = 1; i <= n + 1; i++)
			b[i] = a[i] - a[i - 1];
		for (int i = 1; i <= n + 1; i++) {
			if (b[i] == 1) cnt++;
			else if (b[i] == 0) {
				ans =  ans * (cnt + 1) % mod;
			} else if (b[i] == -1) {
				ans = ans * cnt % mod;
				cnt--;
			} else {
				printf("0\n");
				return 0;
			}
		}
		printf("%lld\n", ans);
	}
	return 0;
}

标签:CF466D,cnt,题意,Sequence,int,memset,long,Increase,序列
From: https://www.cnblogs.com/cloud-evecyx/p/17950744

相关文章

  • Largest Subsequence
    操作:选取词性最大的子序列,向右循环一次问你进行多少次这样的操作能使数组有序,如果不能就输出-1思路:首先要知道的是一个词性最大的序列整个右移过后,数组的新词性最大的序列就是之前的词性最大序列去了最后一个字母.找出词性最大的子序列intn; strings......
  • [ABC271E] Subsequence Path 题解
    [ABC271E]SubsequencePath题解思路解析很好的一道题,很有迷惑性,表面上是一道图论实际上是dp,定义\(f_{i}\)为从\(1\)到\(i\)的最短“好路”。先把每条边对应的起点,终点和边权记录下来,然后输入每个\(e\),由于是子序列顺序不会改变,因此可以顺序进行操作。对于每一个\(e......
  • [ABC216G] 01Sequence
    题目链接很显然,按照右端点从小到大排序,对于每段区间尽量地贪心放在靠右的位置即可。中间用std::set维护当前还是\(0\)的位置,以及树状数组维护区间\(1\)的个数。点击查看代码#include<bits/stdc++.h>#defineFL(i,a,b)for(inti=(a);i<=(b);++i)#defineFR(......
  • 无涯教程-Java 正则 - Matcher reset(CharSequence input)函数
    java.util.regex.Matcher.reset(CharSequenceinput)方法使用新的输入序列重置此匹配器。Matcherreset-声明publicMatcherreset(CharSequenceinput)input - 新的输入字符序列。Matcherreset-返回值这个匹配器。Matcherreset -示例下面的示例显示java.uti......
  • 无涯教程-Java 正则 - Pattern String[] split(CharSequence input)函数
    java.util.regex.Pattern.split(CharSequenceinput)方法将给定的输入序列拆分为该模式的匹配项。String[]split-声明publicString[]split(CharSequenceinput)input  - 要拆分的字符序列。String[]split-返回值通过在此模式的匹配项附近拆分输入来计算的字符......
  • 无涯教程-Java 正则 - Matcher matcher(CharSequence input)函数
    java.util.regex.Pattern.matcher(CharSequenceinput)方法创建一个匹配器,该匹配器将根据该模式匹配给定的输入。Matchermatcher-声明publicMatchermatcher(CharSequenceinput)input  - 要匹配的字符序列。Matchermatcher-返回值此模式的新匹配器。Matcher......
  • CF1621G Weighted Increasing Subsequences
    CF1621GWeightedIncreasingSubsequences你有一个长度为\(n\)的序列,定义\(a\)的一个长度为\(k\)的子序列为\(a_{i_1},a_{i_2},\dots,a_{i_k}\)。由此,我们不难发现,\(a\)的一个长度为\(k\)的子序列为上升子序列,当且仅当\(\forallj\in[1,k)\),\(a_{i_j}<a_{i_{j+1}}\)......
  • PostgreSQL. 异常“more than one owned sequence found”的解决方案
    一、异常信息描述执行数据库操作时,主键id没有自增,且报“morethanoneownedsequencefound”的异常,造成数据没有insert进去,下面是详细的异常信息:java.lang.reflect.InvocationTargetExceptionatsun.reflect.GeneratedMethodAccessor613.invoke(UnknownSource)ats......
  • [Codeforces] CF1811E Living Sequence
    CF1811ELivingSequence这道题洛谷题解的思路比我的更好,可以参考一下题解,但是没人提到我这种做法题意给定一个正整数\(k\)\((1\lek\le10^{12})\),请你输出第\(k\)个数字里没有4的正整数。思路设\(f_i\)表示前\(10^i\)个\(i\)位数里边不含4的数的个数,列举几个如......
  • [Codeforces] CF1817A Almost Increasing Subsequence
    CF1817AAlmostIncreasingSubsequence题意给定长度为\(n\)一个序列\(a\)以及\(q\)次询问,每次询问给出\(l\)和\(r\),找出序列\(a\)在\([l,r]\)内最长的几乎递增子序列。对于几乎递增的定义:如果一个序列中不存在连续的三个数\(x\),\(y\),\(z\),使得\(x\gey\ge\......