小明开始玩起来了数字游戏,他一下子报出了一堆整数,并在报数过程中不断询问在这个数组里,有多少个子区间的积大于 0、等于 0、小于 0 。
输入格式: 输入第一行包括两个整数 n,m,表示小明已近报出的数的数量和后续询问的次数。 第二行包括 n个整数 ,表示小明已经报出的数。 接下来 m行,每行先输入一个整数 op,表示小明的操作: op=1 表示小明要再报一些数,首先会再输入 t,表示报的数的数量,接下来 t个数表示他依次报的数。 op=2 表示小明询问在已经报的数形成的数组里有多少个子区间的积大于 0、等于 0、小于 0。 数据保证至少有一次 op=2的操作。
输出格式:对于每组数据,输出一行一个整数表示答案。
思路:
1:出现零,则零后面的数乘以前面所得的积都是零。所以本题在输入的过程中我们只需记录最后一个零的位置,以及之后一个零以后所有正数、负数子区间的数量即可。
2:如果输入的数是一个正数,则新增加的正数子区间为最后一个零后面所有的正数区间数+1(正数乘以正数为正数,再加上本次输入的这个数本身),新增加的负数区间为最后一个零后面所有的负数子区间数,新增的零区间为之后一个零及其以前所有元素的数量。
3: 如果输入的数是一个负数,则新增加的正数区间是最后一个零后面所有的负数区间数(因为正数乘以负数会变成负数),新增加的负数区间等于最后一个零后面所有的正数区间数+1,新增的零区间为之后一个零及其以前所有元素的数量。(即输入一个负数时,以前的正数区间变为负数区间,负数区间变为正数区间)
4:避免溢出,我们用long long
代码:
#include <stdio.h>
long long n,m,a,op,ans1,ans2,ans3,t,r,temp1,temp2,temp3,q;
void nb(long long x,long long p)
{
if(x==0)
{
ans2+=p;
temp1=0;
temp3=0;
temp2=p;
}
else if(x>0)
{
ans1+=temp1+1;
ans2+=temp2;
ans3+=temp3;
temp1++;
}
else
{
ans1+=temp3;
ans2+=temp2;
ans3+=temp1+1;
q=temp1;
temp1=temp3;
temp3=q+1;
}
}
int main()
{
scanf("%lld%lld",&n,&m);
for(long long i=1;i<=n;i++)
{
scanf("%lld",&a);
nb(a,i);
}
r=n;
while(m--)
{
scanf("%lld",&op);
if(op==1)
{
scanf("%lld",&t);
for(long long i=r+1;i<=r+t;i++)
{
scanf("%lld",&a);
nb(a,i);
}
r+=t;
}
else if(op==2)
{
printf("%lld %lld %lld\n",ans1,ans2,ans3);
}
}
return 0;
}