arc119c

arc119c

首先,观察操作的性质。

如果选定了位置 \(x\) ,那么如果 \(\mid x-y \mid\) 为奇数,就可以将两位同时加或减1,反之,只能将一位加1,并且另一位减1.

然后观察转移。

如果一个区间成立,当且仅当所有数字可以转移到全为0,那么考虑选定一个位置 \(x\) ,从全0开始,所有和 \(x\) 距离为奇数的位置转移成原始序列中相应位置的数,距离偶数的位置保持0不变。

这样,可以得到一个区间是否成立等价于将所有奇数位的值加和到一位上,除去加和的那一位其余奇数位变为0,偶数位不变的这样一个区间是否成立,同理,偶数位也可以这么操作。

这样,一个区间的成立性就转化为奇数位和偶数位的和是否一样。

前缀和处理一下就好。

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)

const int mod = 1e9+7;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;

int n;
ll a[300200];
map<ll, int> e;

int main() {
    cin >> n;
    for(int i=1; i<=n; i++) cin >> a[i];
    for(int i=1; i<=n; i++) {
        if(i&1) a[i] = a[i-1] + a[i];
        else a[i] = a[i-1] - a[i];
        ++ e[a[i]];
    }
    ++ e[0];
    ll ans = 0;
    for(auto k=e.begin(); k!=e.end(); ++k) {
        ll r = k->second;
        // cout << r << "----" << endl;
        ans += r*(r-1)/2;
    }
    cout << ans << endl;
    return 0;
}
/*
5
1 1 1 1 1
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值