[BZOJ3544][ONTAK2010]Creative Accounting(数学相关+set)

来源:互联网 发布:最大公约数 方法 知乎 编辑:程序博客网 时间:2024/06/08 09:13

题目描述

传送门

题解

一段区间的sigma可以转化为前缀和相减
而如果将前缀和都取模m意义下那么所有的都变成了1..m-1中的一个数
那么如果当前的前缀和为x,如何查询x-?的最大值

如果之前的前缀和有比x大的数y,那么答案一定为(x-y)%m
否则为x%m
x-y<0 -> (x-y)%m=m-(y-x)
y<=m -> m-(y-x)>=x
所以实际上就是查询一下是否有比x大的数

那我们拿treap/splay什么的随便维护一下就行了
当然set随便水

代码

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<set>using namespace std;#define LL long longconst LL inf=1000000000000000001LL;int n;LL m,x,sum,now,ans;set <LL> s;int main(){    scanf("%d%lld",&n,&m);    ans=0;sum=0;    s.insert(0);s.insert(inf);    for (int i=1;i<=n;++i)    {        scanf("%lld",&x);x=(x%m+m)%m;        sum=((sum+x)%m+m)%m;s.insert(sum);        if (*s.upper_bound(sum)!=inf) now=*s.upper_bound(sum);        else now=*s.begin();        ans=max(ans,((sum-now)%m+m)%m);    }    printf("%lld\n",ans);}
0 0
原创粉丝点击