CodeForces 1197 D Yet Another Subarray Problem

题面

不得不说CF还是很擅长出这种让人第一眼看摸不着头脑然后再想想就发现是个SB题的题的hhh(请自行断句)。

设sum[]为前缀和数组,那么区间 [l,r]的价值为 sum[r] - sum[l-1] - k*上取整([r-(l-1)]/m)。

或者表示 [l+1,r] 的价值更加简洁一些: sum[r] - sum[l] - k*上取整 ((r-l)/m)。

表示的区间是什么并不重要,我们只在乎后者的最大值,当r确定的时候,值只与 sum[l] + k*上取整 ((r-l)/m) 有关。

我们类似扫描线的做法,每次把右扫描线移动一位(r -> r+1),看看会发生什么:

发现所有 (l%m) == (r%m) 的 l 对应的 sum[l] + k*上取整 ((r-l)/m)  都大了 k,并且还多了一个r的值加了进来,其他的l对应的值都没变。

于是我们直接开个%m意义下的同余系数组记录一下每个等价类的最小值即可,维护是O(1),查询 O(m)。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=300005;

ll a[N],mn[10],ans;
int n,m,k;

inline void solve(const int M){
	memset(mn,0x7f,sizeof(mn));
	mn[0]=k;

	for(int i=1,j=1;i<=n;j++,i++){
		ans=max(ans,a[i]-*min_element(mn,mn+M));
		if(j>=M) j-=M;
		mn[j]=min(mn[j],a[i])+k;
	}
}

int main(){
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++) scanf("%lld",a+i),a[i]+=a[i-1];
	solve(m),printf("%lld\n",ans);
	return 0;
}

  

原文地址:https://www.cnblogs.com/JYYHH/p/11258436.html

时间: 2024-08-30 17:31:00

CodeForces 1197 D Yet Another Subarray Problem的相关文章

CodeForces 459D Pashmak and Parmida&#39;s problem

Pashmak and Parmida's problem Time Limit:3000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 459D Description Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she

Codeforces Round #400 D. The Door Problem(2-sat)

题目链接:Codeforces Round #400 D. The Door Problem 题意: 有n扇门,每扇门有个初始状态,并且受两个开关控制. 现在给你m个开关控制门的信息,每个开关能将它所控制的门的状态翻转. 问能不能通过一定操作,将所以的门的状态都处于开的情况. 题解: 这题用2sat,也可以用并查集判断联通块.这里我用2sat. 因为一个开关可以控制多扇门,而每个门只由两个开关控制,所以这里我们考虑对这m个开关建图. 如果这扇门的状态为1,那么要让它保持1的状态,我们只能同时按下

Codeforces 459D Pashmak and Parmida&#39;s problem(树状数组)

题目链接:Codeforces 459D Pashmak and Parmida's problem 题目大意:给定一个序列,定义f(l,r,x)为l≤k≤r并且ak=x的k的个数,求1≤i<j≤n的情况下,f(1,i,ai)<f(j,n,aj)的个数. 解题思路:预处理出f(1,i,ai),f(j,n,aj)值,然后用树状数组维护个数. #include <cstdio> #include <cstring> #include <algorithm> us

codeforces 459D - Pashmak and Parmida&#39;s problem【离散化+处理+逆序对】

题目:codeforces 459D - Pashmak and Parmida's problem 题意:给出n个数ai,然后定义f(l,?r,?x) 为ak = x,且l<=k<=r,的k的个数,求 i,?j (1?≤?i?<?j?≤?n) ,f(1,?i,?ai)?>?f(j,?n,?aj).,有多少对满足条件的i,j. 分类:逆序数,线段树,离散化, 分析:这是一道不错的数据结构题目,比较灵活.推一下第一组样例之后发现时让求一个逆序数的题目,但是不是单纯的求逆序数. 第一组

D. Yet Another Subarray Problem 思维 难

D. Yet Another Subarray Problem 这个题目很难,我比赛没有想出来,赛后又看了很久别人的代码才理解. 这个题目他们差不多是用一个滑动窗口同时枚举左端点和右端点,具体如下: 首先枚举0~m,这个是说更新的位置,如果是1 当m==3 就更新1 4 7 10... 如果是2,当m==3 就更新 2 6 8 11.... 最后都会被更新的. 核心代码 for (int j = 0; j < n - i; ++j) { s += sum[j]; if (j % m == 0)

@codeforces - [email&#160;protected] Mashmokh&#39;s Designed Problem

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一棵 n 个点的树,每个点的儿子是有序的. 现给定 m 次操作,每次操作是下列三种中的一种: (1)给定 u, v,询问 u, v 之间的距离. (2)给定 v, h,断开 v 到父亲的边,将 v 这棵子树加入到它的第 h 个祖先的最后一个儿子. (3)给定 k,询问在当前这棵树上

codeforces 1197D-Yet Another Subarray Problem

传送门:QAQQAQ 题意:给你一个序列,求一个子序列a[l]~a[r]使得该子序列的sum(l,r)-k*(r-l+1+m+1)/m值是在所有子序列中最大的,并输出最大值 思路:比赛的时候使用O(n)写的,但是被hack了,因为O(n)无法记录当前距离下一次-k还有多少,若用单调队列维护也不知道前面应该弹出多少(可能现在把前面弹出是最优的,但是到后面可能因为个数还没到m的倍数,把前面加进去又是最优的),所以我们考虑再加一维 法一:dp[i][j]表示序列到i截止,这一轮已经进行了j次取数(j=

Codeforces 954I Yet Another String Matching Problem(并查集 + FFT)

题目链接  Educational Codeforces Round 40  Problem I 题意  定义两个长度相等的字符串之间的距离为:   把两个字符串中所有同一种字符变成另外一种,使得两个字符串相等所需要操作的次数的最小值.   求$s$中每一个长度为$t$的长度的连续子串与$t$的距离.字符集为小写字母$a$到$f$ 首先解决求两个长度相等的字符串之间的距离这个问题. $s$和$t$相同位上的字母连一条无向边,最后的答案是$s$和$t$中所有出现过的字符的个数减去这个无向图的连通块

【CodeForces 990C】 Bracket Sequences Concatenation Problem

题目链接 luogu &  CodeForces 题目描述 A bracket sequence is a string containing only characters "(" and ")". A regular bracket sequence is a bracket sequence that can be transformed into a correct arithmetic expression by inserting charact