小圆前辈的数组--前缀和

题意:
求给定数组有多少个连续子序列满足,区间和%k=0且>z
思路:
求区间 [ l , r ] 的和sum%k=0转化为求其前缀和(per[ r ] - per [ l - 1 ])%k=0;
再判断下(per[ r ] - per [ l - 1 ])是否大于z即可。

#include<bits/stdc++.h>
using namespace std;
template <typename T> void debug(string s,T x) { cout <<s<< "=" << x << "\n"; }
typedef long long ll;
typedef unsigned long long ull;
const ll N = 1e6 + 5;
const ll MOD = 1e9 + 7;
const ll INF = 0x7fffffff;
ll suffix[N];
ll trans[N];
vector<ll> pos[N];
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    ll n, k, z;
    cin >> n >> k >> z;
    for (ll i = 1; i <= n; i++) {
        ll t;
        cin >> t;
        suffix[i] = t + suffix[i - 1];
        trans[i] = suffix[i] % k;
        pos[trans[i]].push_back(i);
    }
    ll ans = 0;
    for (ll i = 1; i <= n; i++) {
        ll idx = trans[i - 1];
        for (ll j = 0; j < pos[idx].size(); j++) {
            if (suffix[pos[idx][j]] - suffix[i - 1] >= z)ans++;
        }
    }
    cout << ans;
    
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值