题目描述

给定一个长度为$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. <三剑客> 老二:sed命令用法

    sed命令的用法: sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space ...

  2. CF704E Iron Man

    CF704E Iron Man 经过不懈(抄题解)努力之后,终于AC了此题. 说起来很简单. 考虑一个链上的情况, 建立直角坐标系. 横坐标是t,纵坐标是距离链开头的距离d m个路径就是一个线段 那么 ...

  3. Dealing with exceptions thrown in Application_Start()

    https://blog.richardszalay.com/2007/03/08/dealing-with-exceptions-thrown-in-application_start/ One a ...

  4. IDEA默认快捷键

    idea常用快捷键大全   Idea常用快捷键大全,拿小本本记下来,忘记了可以方便查找.编写代码Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最 ...

  5. 52-python基础-python3-列表-常用列表方法- reverse()方法

    reverse()方法 永久性地修改列表元素的排列顺序,但可随时恢复到原来的排列顺序,为此只需对列表再次调用reverse() 即可. 实例:  

  6. int类型转换舍入问题

    一,看代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sy ...

  7. windows修改docker的默认存放位置

    docker默认存储到c盘,我需要移动到其他盘. 参考了网上很多资料,结果要么移动不了,要么重启docker就回到c盘了. 最后参考docker的官方论坛,找到了解决方案.https://forums ...

  8. 八、hibernate的查询(HQL)

    HQL:Hibernate Query Language 提供更加丰富灵活.更为强大的查询能力 HQL更接近SQL语句查询语法 面向对象的查询 "from Children where ci ...

  9. IDEA compile successfully many errors still occur

    Compile and install successfully with maven in IDEA, but error prompt still popup. Your local enviro ...

  10. SQL数据库—<8>触发器

    触发器:一.什么是触发器?    一段SQL代码,挂到某个表的某个增.删.改的操作上.    当这个表执行相应的操作时,就会触发这段相应的SQL代码.触发器与存储过程的区别:1.存储过程是独立于表存在 ...