给定一个数列 A = (a1, a2, · · · , an),问有多少个区间 [L, R] 满足区间内元素的乘积等于他们的和,即 aL · aL+1 · · · aR = aL + aL+1 + · · · + aR 。
输入
输入第一行包含一个整数 n,表示数列的长度。
第二行包含 n 个整数,依次表示数列中的数 a1, a2, · · · , an。
输出
输出仅一行,包含一个整数表示满足如上条件的区间的个数。
样例输入复制
4 1 3 2 2
样例输出复制
6
提示
【样例解释】
符合条件的区间为 [1, 1], [1, 3], [2, 2], [3, 3], [3, 4], [4, 4]。
【评测用例规模与约定】
对于 20% 的评测用例,n ≤ 3000;
对于 50% 的评测用例,n ≤ 20000;
对于所有评测用例,1 ≤ n ≤ 200000, 1 ≤ ai ≤ 200000。
本题思路
我写这题的时候没有想太多,基本思想就是一个存从i开始的乘积数组,一个存加和数组,然后每遇到一个新的就刷新前面的数组,然后如果相等就+1
整体思路很简单,不过最后数据只能过64%
下面上代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Main和与乘积 {
public static void main(String[] args) throws IOException {
StreamTokenizer x=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out=new PrintWriter(System.out);
x.nextToken();
int n=(int)x.nval;
int aa[]=new int[n];
long sum=0,max=0;
for(int i=0;i<n;i++) {
x.nextToken();
aa[i]=(int)x.nval;
max+=aa[i];
}
long bb[]=new long[n];//存乘积
long cc[]=new long[n];//存加和
int beg=0;
Arrays.fill(bb, 1);
for(int i=0;i<n;i++) {
for(int j=beg;j<=i;j++) {
bb[j]*=aa[i];
cc[j]+=aa[i];
if(bb[j]==cc[j])
sum++;
if(bb[j]>max)//如果乘积大于相加最大,就缩小更新区间
beg=j+1;
}
}
out.println(sum);
out.flush();
}
}