1 条题解
-
0
首先,枚举的写法肯定不可取。
很明显可以发现能够影响答案的只有区间内负数的数量。
用前缀和数组维护当前位置一共有多少负数出现。
先·计算出l=1时对答案的贡献,剩下的分类讨论即可:
从l=2开始,令前一位对答案的贡献为(同上):
如果当前位置负数出现次数为偶数,且当前数为正
则该位置对答案贡献为,
如果当前位置负数出现次数为奇数,且当前数为正
则该位对答案的贡献为,-1。
其他两种情况同理
每次维护贡献求值即可
#include<bits/stdc++.h> #define int long long using namespace std; int a[200005]; int b[200005]; signed main() { int n; cin >> n; for(int i=1;i<=n;i++) { cin >> a[i]; if(a[i]<0) a[i]=1;//小于0为1,否者为0 else a[i]=0; } int ans1=0,ans2=0; for(int i=1;i<=n;i++) { b[i]+=a[i]+b[i-1];//当前位置出现的负数数目 b[i]=b[i]%2; if(b[i]%2==0) ans1++; else ans2++; } int o=ans1,p=ans2; if(b[1]%2) p--; else o--; for(int i=2;i<=n;i++) { if(a[i]!=b[i])//分类讨论 { ans1+=p; ans2+=o; } else { ans1+=o; ans2+=p; } if(b[i]%2)//维护贡献 p--; else o--; } cout<<ans1<<" "<<ans2<<'\n'; }
- 1
信息
- ID
- 1066
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- (无)
- 递交数
- 195
- 已通过
- 8
- 上传者