HDU 5875 Function(RMQ-ST+二分) 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 .
You job is to calculate ).
You are given an array .
You job is to calculate ).
Input
There are multiple test cases.
The first line of input contains a integer T test cases follow.
For each test case, the first line contains an integer ).
The second line contains ).
The third line contains an integer M denoting the number of queries.
The following ), representing a query.
The first line of input contains a integer T test cases follow.
For each test case, the first line contains an integer ).
The second line contains ).
The third line contains an integer M denoting the number of queries.
The following ), representing a query.
Output
For each query) 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 ", 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 ", res); } } } return 0; }