时间限制:
4000 ms | 内存限制:
65535 KB
难度:
2
描述
-
mod是取余运算,在程序中用符号"%"来表示。
如3 % 7 = 3,7 % 5 = 2,0 % 4 = 0。
Ocean用巧妙的方法

得到了一个序列,该序列有
N
N 个元素,我们用数组
a
a 来记录(下标从
0
0 到
N−1
Ocean定义f[i] = (((i % a[0]) % a[1]) % ...) % a[N-1]。
现在Ocean会给出Q次查询,每次给定一个区间[L, R],他想快速知道f[L] + ... + f[R]的值。
输入
-
第一行输入一个整数T,代表有T组测试数据。
每组数据占多行,第一行输入一个整数N,代表元素个数。
下面一行输入N个整数ai。
下面一行输入一个整数Q,代表Q次查询。
接下来Q行,每行输入两个整数L, R,代表查询的区间。
注:1 <= T <= 20,1 <= N,Q <= 1000,1 <= ai <= 100000,1 <= L <= R <= 100000。
输出
-
对每组数据,依次输出Q行,每行输出对应的查询结果。
样例输入
-
2
5
5 4 3 2 1
4
1 100000
2 100000
3 100000
4 100000
5
5 5 5 5 5
4
1 100000
2 100000
3 100000
4 100000
样例输出
0
0
0
0
200000
199999
199997
199994
来源
第七届河南理工大学程序设计大赛
上传者
liuyuqiang
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
int a[1005];
int b[100005];
int E_F(int *p,int r,int R,int L)
{
int mid;
while(L!=R)
{
mid=(L+R)/2;
if(a[mid]>r)
L=mid+1;
else if(a[mid]<r)
R=mid;
else
return mid;
}
return L;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m,l=1;
scanf("%d%d",&n,&a[0]);
for(int i=1;i<n;i++)
{
scanf("%d",&m);
if(a[l-1]>m)
a[l++]=m;
}
int k=1;
for(int i=1;i<=100000;i++)
{
int u=i,pp=0;
while(1)
{
if(u<a[l-1])
break;
int o=E_F(a,u,l-1,pp);
u%=a[o];
pp=o+1;
}
b[i]=b[i-1]+u;
}
int p,pl,pr;
scanf("%d",&p);
for(int i=0;i<p;i++)
{
scanf("%d%d",&pl,&pr);
printf("%d\n",b[pr]-b[pl-1]);
}
}
}