题目描述
给你一条直线上的n个方格,每个方格踩下去有一个权值,小A踩方格的路线为1-3-5-7-9....小B踩方格的路线为2-4-6-8-10,现在你可以提前去掉一个方格,小A踩方格的路线仍为1-3-5-7-9....小B踩方格的路线仍为2-4-6-8-10,现在问有多少种去掉方格的方案使得小A和小B获得的权值和相同。
输入
第一行一个正整数n。
第二行n个数表示从前到后每个方格的权值。
n<=200000,0<=权值<=10000。
输出
一个数表示方案数。
样例输入
7
5 5 4 5 5 5 6
样例输出
2
提示
对于8%的数据,n<=10;
对于40%的数据,n<=2000;
对于100%的数据,n<=200000;
解析:
巧妙利用前缀和,完成离线单点修改嘿嘿。
记录的是奇数前缀和和偶数前缀和,第一个奇数,第二个这样。。。
最后判断条件的时候不要忘了左边的奇数或偶数和要减掉当前数(如果需要的话),但是右边的不要减掉,因为已经是到当前数的前缀和了,最后暴力枚举可以了。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=200000+10;
int n,a[maxn],s1[maxn],s2[maxn],sum1,sum2;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
if(i&1)
{
s1[(i+1)/2]+=(a[i]+s1[(i+1)/2-1]);
sum1+=a[i];
}
else if(i%2==0)
{
s2[i/2]+=(a[i]+s2[i/2-1]);
sum2+=a[i];
}
}
int cnt=0;
for(int i=1;i<=n;i++)
{
int x=s1[(i+1)/2]; //左边奇数和
int y=s2[(i)/2]; // 左边偶数和
int t1=x;
int t2=y;
if(i&1)
x-=a[i];
else
y-=a[i];
if(x+sum2-t2==y+sum1-t1)
cnt++;
}
printf
return 0;
}