BZOJ 3544 ONTAK 2010 Creative Accounting 贪心+平衡树

题目大意:给出一段区间,和一个树p,请找出一段区间,使得这段区间和%p的值最大。

思路:利用前缀和的思想,用set维护出现过的所有的前缀和。对于一个前缀和m来说,如果之前出现过(m + 1) % p是最好的,这样就可以达到最大。所以就找之前出现过比(m + 1)大的数,如果没有就贪心的取begin()。然后更新答案。

负数取模还是要好好搞搞。

CODE:

#include <set>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 200010
using namespace std;

int cnt;
long long src[MAX],p;

set<long long> G;

int main()
{
	cin >> cnt >> p;
	long long ans = 0;
	G.insert(0);
	for(int i = 1; i <= cnt; ++i) {
		scanf("%lld",&src[i]);
		src[i] %= p;
		if(src[i] < 0)	src[i] += p;
		src[i] = (src[i - 1] + src[i] % p) % p;
		set<long long>::iterator it = G.lower_bound(src[i] + 1);
		if(it == G.end())	it = G.begin();
		ans = max(ans,(src[i] - *it + p) % p);
		G.insert(src[i]);
	}
	cout << ans << endl;
	return 0;
}

时间: 2024-10-13 23:28:44

BZOJ 3544 ONTAK 2010 Creative Accounting 贪心+平衡树的相关文章

【BZOJ3544】[ONTAK2010]Creative Accounting 前缀和+set

[BZOJ3544][ONTAK2010]Creative Accounting Description 给定一个长度为N的数组a和M,求一个区间[l,r],使得(\sum_{i=l}^{r}{a_i}) mod M的值最大,求出这个值,注意这里的mod是数学上的mod Input 第一行两个整数N,M.第二行N个整数a_i. Output 输出一行,表示答案. Sample Input 5 13 10 9 5 -5 7 Sample Output 11 HINT [数据范围]N<=200000

[bzoj 1911][Apio 2010]特别行动队(斜率优化DP)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1911 分析: 首先可以的到裸的方程f[i]=max{f[j]+a*(Si-Sj)^2+b*(Si-Sj)+c} 0<j<i 简化一下方程,我们知道对于一次项,最后结果肯定是b*Sn 所以可以写成f[i]=max{f[j]+a*(Si-Sj)^2+c} 0<j<i 我们不妨设0<x<y<i,且x比y优 即f[x]+a*(Si-Sx)^2+c>f[y]+a*

bzoj 2120: 数颜色 线段树套平衡树

/************************************************************** Problem: 2120 User: wangyucheng Language: C++ Result: Time_Limit_Exceed ****************************************************************/ #include<iostream> #include<cstdio> #incl

【BZOJ 3545】【ONTAK 2010】Peaks &amp; 【BZOJ 3551】【ONTAK 2010】Peaks加强版 Kruskal重构树

sunshine的A题我竟然调了一周!!! 把循环dfs改成一个dfs就可以,,,我也不知道为什么这样就不会RE,但它却是A了,,, 这周我一直在调这个题,总结一下智障错误: 1.倍增的范围设成了n而不是n*2-1,,, 2.重构树的顶点是n*2-1,而我一开始设成了n,,, 3.define里的for3和for4的i--打成i++,,,,,,,,,,,, 4.dfs爆栈了,找CA爷问的编译命令里手动扩栈,真是愚蠢的问题,,,, 比赛时绝不会有太多时间,在这么犯逗就得滚粗了QAQ 3545: #

【BZOJ 2151】 2151: 种树 (贪心+堆)

2151: 种树 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度.但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i号位置和i+1号位置叫相邻位置.值得注意的是1号和n号也算相邻位置!).最终市政府给园林部门提供了m棵树苗并要求全部种上,请你帮忙设计种树方案使得美观度总和最大.如果无法将m棵树苗

BZOJ3544 [ONTAK2010]Creative Accounting

看不懂题,就不能写的稍微像人话点吗我去... 题目就是要找一段区间使得Σai mod m的值最大. 于是嘛...前缀和一下再贪心就好了. 先求出前i个数的前缀和s,然后用s更新解. 还有可能就是前面的某个前缀和s1刚好在mod m意义下大于s且是最小的一个,那么这一段的和就是m + s - s1,再用它来更新解. 1 /************************************************************** 2 Problem: 3544 3 User: ra

[BZOJ 1029] [JSOI2007] 建筑抢修 【贪心】

题目链接:BZOJ - 1029 题目分析 使用一种贪心策略. 现将任务按照deadline从小到大排序. 然后枚举每一个任务,如果当前消耗的时间加上完成这个任务的时间不会超过这个任务的deadline,那么就完成这个任务. 否则,如果完成这个任务的时间比之前选择完成的任务中完成时间最长的一个要短,那么就弹出之前完成的那个任务,换上当前的这个任务. 这样当前的答案没有变,当前消耗的时间却减少了. 用堆来实现取最大值的操作. 代码 #include <iostream> #include <

[BZOJ 1028] [JSOI2007] 麻将 【枚举+贪心判断】

题目链接:BZOJ - 1028 题目分析 枚举听的是哪种牌,再枚举成对的是哪种牌,再贪心判断: 从1到n枚举每一种牌,如果这种牌的个数小于0,就返回不合法. 将这种牌的张数 % 3, 剩下的只能和 i + 1, i + 2 这两种牌构成顺,所以 Num[i + 1] -= Num[i]; Num[i + 2] -= Num[i]; 牌的种类要枚举到 n + 2,因为第 n - 1 和第 n 种牌可能会减掉 n + 1,n + 2 的牌. 代码 #include <iostream> #inc

BZOJ 1692: [Usaco2007 Dec]队列变换( 贪心 )

数据 n <= 30000 , 然后 O( n² ) 的贪心也过了..... USACO 数据是有多弱啊 = = ( ps : BZOJ 1640 和此题一模一样 , 双倍经验 ) -------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #