Mod
时间限制:
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
来源
- 第七届河南理工大学程序设计大赛
-
-
- AC代码:
-
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; typedef long long LL; const int MAXN=1e5+1; bool vis[MAXN+11]; int a[1011],ans[MAXN+11]; queue<int> Q; int B_S(int n,int cnt) {//很快的 就差这一个数量级 int L=0,R=cnt; while(L<R) { int mid=L+R>>1; if(a[mid]<=n) { R=mid-1; } else L=mid+1; } return L; } int main() { int T; scanf("%d",&T); while(T-- ) { int N; scanf("%d",&N); int cnt=0; for(int i=0;i<N;++i) { int tem; scanf("%d",&tem); if(i==0||tem<a[cnt-1]) a[cnt++]=tem; } memset(vis,false,sizeof(vis)); int i=0; for(i=1;i<a[cnt-1];++i) { ans[i]=i; vis[i]=true; } for( ;i<MAXN;++i) { int tem=i; for(int j=B_S(tem,cnt);j<cnt;++j) { if(vis[tem]) break; Q.push(tem); tem%=a[j]; } while(!Q.empty() ) { int F=Q.front(); Q.pop(); if(!vis[F]) { vis[F]=true; ans[F]=ans[tem]; } else break; } while(!Q.empty()) Q.pop(); } ans[0]=0; for(int i=1;i<MAXN;++i) ans[i]+=ans[i-1]; int ask; scanf("%d",&ask); while(ask--) { int L, R; scanf("%d%d",&L,&R); printf("%d\n",ans[R]-ans[L-1]); } } return 0; }
-
-
第一行输入一个整数T,代表有T组测试数据。