AtCoder E - Rem of Sum is Num(区间:前缀同余)

题目链接
题意
给你一个区间,然后在这个找一个子区间,使得这个子区间的和 % k = k= k=(这个区间的数字个数)。
思路
一个很朴素的想法是预处理前缀和,然后 O ( n 2 ) O(n^2) O(n2)枚举,但是很遗憾 的是这里 n n n的范围太大了,这样的做法肯定T。
我们预处理的前缀和为 S S S
根据上面朴素算法的思想得
(   S ( r ) − S ( l − 1 )   ) % k = ( r − l + 1 ) (\ S( r ) - S(l-1)\ )\%k=(r-l+1) ( S(r)S(l1) )%k=(rl+1)
S ( r ) − S ( l − 1 ) ≡ r − l + 1 ( m o d   k ) S(r)-S(l-1)\equiv r-l+1(mod\ k) S(r)S(l1)rl+1(mod k)
S ( r ) − S ( l − 1 ) = r − l + 1 + k ∗ y S(r)-S(l-1)=r-l+1+k*y S(r)S(l1)=rl+1+ky
( S ( r ) − r ) % k = ( S ( l − 1 ) − ( l − 1 ) ) % k (S(r)-r)\%k=(S(l-1)-(l-1))\%k (S(r)r)%k=(S(l1)(l1))%k
所以我们只需要处理下前缀和,找到区间内满足上面条件的就行了,但是有 % k \%k %k条件,所以区间长度要小于 m m m,这时我们设置个划窗就行。
这个题目非常要注意的一点是关于边界的处理,一不小心就可能卡很长时间。
首先,我们处理前缀和的范围是 0 到 n 0到n 0n,然后划窗的长度为m,这时你可能有疑问,不是区间长度要小于m啊,应该设为m-1啊?
记住,你处理的是前缀和!!!
A C   C o d e : AC \ Code: AC Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;

const int N = 2e5+1000;
#define ll long long
#define read(x) scanf("%d",&x)
#define Read(x,y) scanf("%d%d",&x,&y)
#define gc(x) scanf(" %c",&x)
#define sread(x,y,z) scanf("%d%d%d",&x,&y,&z)
ll f[N];
map<ll,ll> hap;
int main()
{
    int n,m;
    Read(n,m);
    for(int i = 1;i <= n;++i){
        scanf("%lld",&f[i]);
        f[i] += f[i-1];
    }
    for(int i = 1;i <= n;++i){
        f[i] = (f[i] - i) % m;
    }
    m --;//与下面那句顺序不能反
    m = min(m,n);
    for(int i = 0;i < m;i ++ ){
        hap[f[i]] ++;
    }
    ll sum = 0;
    for(int i = m ;i <= n;++i){
        hap[f[i]] ++;
        sum += hap[f[i-m]] - 1;
        hap[f[i-m]] --;
    }
    for(int i = n-m + 1;i <= n;++i){
        sum += hap[f[i]] - 1;
        hap[f[i]] --;
    }
    cout<<sum;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值