Function
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2427 Accepted Submission(s): 858
Problem Description
The shorter, the simpler. With this problem, you should be convinced of this truth.
You are given an array A of N postive integers, and M queries in the form (l,r). A function F(l,r) (1≤l≤r≤N) is defined as:
F(l,r)={AlF(l,r−1) modArl=r;l<r.
You job is to calculate F(l,r), for each query (l,r).
You are given an array A of N postive integers, and M queries in the form (l,r). A function F(l,r) (1≤l≤r≤N) is defined as:
F(l,r)={AlF(l,r−1) modArl=r;l<r.
You job is to calculate F(l,r), for each query (l,r).
Input
There are multiple test cases.
The first line of input contains a integer T, indicating number of test cases, and T test cases follow.
For each test case, the first line contains an integer N(1≤N≤100000).
The second line contains N space-separated positive integers: A1,…,AN (0≤Ai≤109).
The third line contains an integer M denoting the number of queries.
The following M lines each contain two integers l,r (1≤l≤r≤N), representing a query.
The first line of input contains a integer T, indicating number of test cases, and T test cases follow.
For each test case, the first line contains an integer N(1≤N≤100000).
The second line contains N space-separated positive integers: A1,…,AN (0≤Ai≤109).
The third line contains an integer M denoting the number of queries.
The following M lines each contain two integers l,r (1≤l≤r≤N), representing a query.
Output
For each query
(l,r), output
F(l,r) on one line.
Sample Input
1
3
2 3 3
1
1 3
Sample Output
2
题目链接:HDU 5875
题意就是给定区间[L,R],求A[L]%A[L+1]%A[L+2]%……%A[R]的值,这里有一个技巧,可以发现在b>a时,a%b是无意义的,即结果还是a,因此把取模过程改一下,每一次从当前位置idx向右二分找到第一个值小于A[idx]的数,然后对它取模,然后这样迭代地继续寻找,直到在idx~r中找不到这样的位置即可。对了这题其实最大的意义是让我知道了log类函数常数比较大,一开始交用这个函数超时,不管是log2还是log都这样,因此用位运算模拟来求这个指数k。
代码:
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 100007;
int arr[N], Min[N][18];
int Scan()
{
int res = 0, ch, flag = 0;
if ((ch = getchar()) == '-') //判断正负
flag = 1;
else if (ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9' )
res = (res << 3) + (res << 1) + ch - '0';
return flag ? -res : res;
}
void RMQ_init(int l, int r)
{
int i, j;
for (i = l; i <= r; ++i)
Min[i][0] = arr[i];
for (j = 1; l + (1 << j) - 1 <= r; ++j)
for (i = l; i + (1 << j) - 1 <= r; ++i)
Min[i][j] = min(Min[i][j - 1], Min[i + (1 << (j - 1))][j - 1]);
}
inline int ST(int l, int r)
{
int len = r - l + 1;
int k = 0;
while (1 << (k + 1) <= len)
++k;
return min(Min[l][k], Min[r - (1 << k) + 1][k]);
}
int getfirstpos(int key, int l, int r)
{
int L = l, R = r;
int ans = -1;
while (L <= R)
{
int mid = (L + R) >> 1;
if (ST(l, mid) <= key)
{
ans = mid;
R = mid - 1;
}
else
L = mid + 1;
}
return ans;
}
int main(void)
{
int tcase, n, m, l, r, i;
scanf("%d", &tcase);
while (tcase--)
{
scanf("%d", &n);
getchar();
for (i = 1; i <= n; ++i)
arr[i] = Scan();
RMQ_init(1, n);
scanf("%d", &m);
while (m--)
{
scanf("%d%d", &l, &r);
if (l == r)
printf("%d\n", arr[l]);
else
{
int idx = l;
int res = arr[l];
int pos;
while (idx + 1 <= r && ~(pos = getfirstpos(res, idx + 1, r)) && res)
{
res %= arr[pos];
idx = pos;
}
printf("%d\n", res);
}
}
}
return 0;
}