题目描述

给定一个长度为$n$的序列$a$以及常数$k$,序列从$1$开始编号。
记
$$f(l,t)=\sum \limits_{i=l}^ra_i-\max \limits_{i=l}^r\{a_i\}$$
求合法的正整数对$(l,r)$的数量,满足$1\leqslant l<r\leqslant n$,且$k|f(l,r)$。


输入格式

第一行两个正整数$n$和$k$。
第二行包含$n$个正整数,第$i$个正整数表示$a_i$。


输出格式

一行一个正整数,表示答案。


样例

样例输入1:

4 3
1 2 3 4

样例输出1:

3

样例输入2:

4 2
4 4 7 4

样例输出2:

6


数据范围与提示

对于$30\%$的数据,$n\leqslant 3,000$;
对于另外$20\%$的数据,数列$a$为随机生成;
对于$100\%$的数据,$1\leqslant n\leqslant 3\times {10}^5,1\leqslant k\leqslant {10}^6,1\leqslant a_i\leqslant {10}^9$。


题解

考虑分治,但是我的打法跟正解不太一样。

$solve(l,r)$代表左右端点都在$[l,r]$之间的合法区间数量。

显然我们肯定不能依次枚举每个端点,这样的时间复杂度还是$\Theta(n^2)$的,所以我们考虑优化。

我们可以指枚举一侧,然后在处理另一侧的时候计算这一侧的答案即可。

时间复杂度:$\Theta(n\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[300001];
int s[300001];
int maxn[300001],pos[300001];
int t1[10000001],t2[10000001];
long long ans;
void wzc(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
int flag1=1,flag2=mid+1,mx=0;
s[0]=s[mid]=maxn[0]=0;
for(int i=mid+1;i<=r;i++)
{
if(a[i]>a[maxn[maxn[0]]])maxn[++maxn[0]]=i;
s[i]=(s[i-1]+a[i])%k;
t1[(s[i]-a[maxn[maxn[0]]]%k+k)%k]++;
pos[i]=maxn[maxn[0]];
}
maxn[maxn[0]+1]=r+1;
for(int i=mid;i>=l;i--)
{
s[0]=(s[0]+a[i])%k;
mx=max(mx,a[i]);
while(flag1<=maxn[0]&&a[maxn[flag1]]<=mx)flag1++;
while(flag2<maxn[flag1])
{
t1[(s[flag2]-a[pos[flag2]]%k+k)%k]--;
t2[s[flag2++]]++;
}
if(flag1<=maxn[0])ans+=t1[(k-s[0])%k];
ans+=t2[(mx%k-s[0]+k)%k];
}
for(int i=mid+1;i<flag2;i++)t2[s[i]]--;
for(int i=flag2;i<=r;i++)t1[(s[i]-a[pos[i]]%k+k)%k]--;
wzc(l,mid);
wzc(mid+1,r);
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
wzc(1,n);
printf("%lld",ans);
return 0;
}

rp++

[CSP-S模拟测试]:简单的区间(分治)的更多相关文章

  1. noip模拟12[简单的区间·简单的玄学·简单的填数]

    noip模拟12 solutions 这次考试靠的还是比较好的,但是还是有不好的地方, 为啥嘞??因为我觉得我排列组合好像白学了诶,文化课都忘记了 正难则反!!!!!!!! 害没关系啦,一共拿到了\( ...

  2. [CSP-S模拟测试]:简单的括号序列(组合数)

    题目传送门(内部题82) 输入格式 一行一个字符串$ss$,保证$ss$中只包含$'('$和$')'$. 输出格式 一行一个整数,表示满足要求的子序列数对$10^9+7$的结果. 样例 样例输入1: ...

  3. [CSP-S模拟测试]:Revive(点分治)

    题目背景 $Sparkling\ ashes\ drift\ along\ your\ flames \\ And\ softly\ merge\ into\ the\ sky$ 题目传送门(内部题1 ...

  4. [CSP-S模拟测试]:蛋糕(区间DP)

    题目传送门(内部题34) 输入格式 第一行,一个正整数$n$.第二行,$n$个正整数$a_i$,保证$a_i$互不相等. 输出格式 一行一个整数表示间宫卓司得到的蛋糕大小总和的最大值. 样例 样例输入 ...

  5. [CSP-S模拟测试]:简单计算(数学)

    题目传送门(内部题104) 输入格式 第一行一个正整数$T$,表示该测试点内的数据组数,你需要对该测试点内的$T$组数据都分别给出正确的答案才能获得该测试点的分数. 接下来$T$组数据,每组数据一行两 ...

  6. [CSP-S模拟测试]:简单的操作(二分图+图的直径)

    题目描述 从前有个包含$n$个点,$m$条边,无自环和重边的无向图. 对于两个没有直接连边的点$u,v$,你可以将它们合并.具体来说,你可以删除$u,v$及所有以它们作为端点的边,然后加入一个新点$x ...

  7. [CSP-S模拟测试]:简单的期望(DP)

    题目描述 从前有个变量$x$,它的初始值已给出. 你会依次执行$n$次操作,每次操作有$p\%$的概率令$x=x\times 2$,$(100−p)\%$的概率令$x=x+1$. 假设最后得到的值为$ ...

  8. [CSP-S模拟测试]:简单的序列(DP)

    题目描述 从前有个括号序列$s$,满足$|s|=m$.你需要统计括号序列对$(p,q)$的数量. 其中$(p,q)$满足$|p|+|s|+|q|=n$,且$p+s+q$是一个合法的括号序列. 输入格式 ...

  9. [CSP-S模拟测试]:简单的填数(贪心+模拟)

    题目描述 对于一个长度为$n$,且下标从$1$开始编号的序列$a$,我们定义它是「合法的」,当且仅当它满足以下条件:·$a_1=1$·对于$i\in [1,n),a_i\leqslant a_{i+1 ...

随机推荐

  1. 9.28 linux系统基础优化

    关闭SELinux(是美国安全局对强制访问的实现)功能 [root@wen ~]# sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selin ...

  2. PHP 常用自定义函数

    模拟 POST.GET 请求 /** * 模拟post进行url请求 * @param string $url * @param string $param */ protected function ...

  3. springBootJpa 联表分页查询总数不准的问题

    问题情景: 在联表查询时 ``` // 两张表关联查询 Join<Project, Plan> planJoin = root.join("plans", JoinTy ...

  4. selenium2-java 浏览器cookie的获取

    //成功登陆后增加如下代码        File cookieFile = new File("C:\\tmp\\tangdai.cookie.txt");           ...

  5. delphi 在代码中 添加 TO-DO 并且 管理

    TO-DO List是一项非常好用的功能.采用她可以让我们很清楚的了解以前完成了那些任务,还有哪些任务需要做,由谁负责完成,是不是比较紧急的任务等.今天来不及完成的,明天上班就可以很快的找到任务所在的 ...

  6. mysql null 值查询问题

    我在开发公司内部的一个项目时遇到一个问题:select student_quality_id from STUDENT_QUALITY where mark_status=0 and batch_st ...

  7. latex的资料ftp

    ftp://ftp.tex.ac.uk/ctan/tex-archive/ ftp ftp.tex.ac.uk anonymous ls

  8. git 资料

    git学习资料整理(知乎搜集的) https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 ...

  9. bootstrap3- 导航条 - 慕课笔记

    bootstrap中的导航条 一.和导航的区别 导航条比导航多了一个条字 直接上图 导航: 导航条: 简单文字描述: 由两张图看出,导航内容比较简单,而导航条可以包含导航及其他元素,如表单,搜索框等, ...

  10. pychrm和linux进行链接上传代码

    众享周知:现在在windows文件中我们有pycharm工具帮我们去编辑python脚本,这会省去我们大把的时间让我们进行更多的脚本编辑.有这样的一种方法,我们可以使用pycharm编辑的脚本上传到l ...