题目地址:http://codeforces.com/contest/1215/problem/B
题意:给你一个值都不为零的数组,分别找出有多少个连续的子串乘积小于零,大于零。
我的思路:先找出为正数的基础子串x个,即单个正数或两个负数连起来的子串算一个,可算得。。。算了一直wrong在样例7.还没想出来那错了,就不写了。
别人家的思路:从首开始找负数字串,即有一个负数后,在下一个负数前这里面的都是负数子串。而其他的就为正数子串,正数子串初始化应为1,所以得的正数子串最后应加上1。两个负数作为边上的元素的子串也可看为一个正数子串,负数子串和正数子串的乘积即为子串乘积为负数的数量。这里面看似有重复(我也想了挺久的),其实并没有,例如 ”-1,2,3,-4“这个数组,它的负数子串为3,正数子串为2,3×2=3,这个2,一个是-1,一个是-4。多成了一个自己等于算上后面的负数。负数个数出来了,用总数n×(n+1)/2减去负数个数便是正数的个数。
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 typedef long long ll; 6 int main(){ 7 ll n; 8 cin>>n; 9 ll a,num1=0,num2=1,t=1; 10 //num1记录负子串个数,num2记录正子串个数,t表判断 11 for(ll i=0;i<n;i++){ 12 cin>>a; 13 if(a<0) t*=-1; 14 if(t>0) num2++; 15 else num1++; 16 } 17 cout<<num1*num2<<" "<<n*(n+1)/2-num1*num2<<endl; 18 return 0; 19 }