Problem Description
The shorter, the simpler. With this problem, you should be convinced of this truth.
You are given an array ).
You are given an array ).
Input
There are multiple test cases.
The first line of input contains a integer ), representing a query.
The first line of input contains a integer ), representing a query.
Output
For each query) on one line.
Sample Input
1
3
2 3 3
1
1 3
Sample Output
2
题意:
给你一个n,n个数
m个询问,每次询问你 l,r,, a[l] % a[l+1] % a[l+2] %……a[r] 结果是多少
题解;
每次有效的取模会使结果减半,因此只有log次有效取模,每次往右找一个不大于结果的最靠左的数,ST表+二分
注意RMQ查询的时候少用 log函数,这是造成我开始超时的原因
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<vector> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18; const double Pi = acos(-1.0); const int N = 1e5+10, M = 1e2+11, mod = 1e9+7, inf = 2e9; int dp[N][50],a[N],n,q; void st() { for(int j = 1; (1<<j) <= n; ++j) { for(int i = 1; (i + (1<<j) - 1) <= n; ++i) { dp[i][j] = min(dp[i][j-1],dp[i + (1<<(j-1))][j-1]); } } } int query(int l,int r) { int len = r - l + 1; int k = 0; while ((1 << (k + 1)) <= len) k++; return min(dp[l][k],dp[r - (1<<k) + 1][k]); } int _binary_search(int l,int r,int res) { int s = r+1; while(l <= r) { int md = (l + r) >> 1; if(query(l,md) <= res) r = md - 1,s = md; else l = md + 1; } return s; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i = 1; i <= n; ++i) scanf("%d",&a[i]),dp[i][0]=a[i]; st(); scanf("%d",&q); for(int i = 1; i <= q; ++i) { int x,y,L,R; scanf("%d%d",&x,&y); int res = a[x]; L = x+1, R = y; while(L <= R && res) { L = _binary_search(L,R,res); if(L<=R) { res%=a[L];L++; } } printf("%d\n",res); } } return 0; }