water problem
发布时间: 2015年10月10日 15:34 时间限制: 1000ms 内存限制: 256M
描述
题意很简单
给你N个数, Q个查询
每次查询给你一个区间[L, R]
你要找出 [L, R] 这个区间里面取模M后的最大值。
输入
第一行一个T,表示测试数据组数。
第二行两个整数N, M (1<=N<=10^5, 1<=M<=10^9)。
第三行给你N个整数 整数范围在1到10^9之间。
第四行给你一个整数Q. ( 1<=Q<=10^5)
下面Q行, 每一行对应两个整数L, R (1<=L<=R<10^9)
输出
每一行对应一个询问的答案。
样例输入1
1
5 3
4 2 2 3 5
2
1 3
4 5
样例输出1
2
2
题意很简单是吧,当初没学线段树的时候看完这道题觉得这题和它的名字真配,结果交了几次都是T。
学完线段树在看这道题,才发现这道题依然和名字很配。。就是线段树的模板题,没什么好说的。
#include <cstdio>
#include <algorithm>
using namespace std;
const int M = 1e5 + 5;
struct Node
{
int l, r, val;
}seg[M*4];
int a[M];
void pushUp(int rt)
{
seg[rt].val = max(seg[rt<<1].val, seg[rt<<1|1].val);
}
void build(int rt, int L, int R)
{
seg[rt].l = L;
seg[rt].r = R;
if(L==R)
{
seg[rt].val = a[L];
return;
}
int m = (seg[rt].l + seg[rt].r) >> 1;
build(rt<<1, seg[rt].l, m);
build(rt<<1|1, m+1, seg[rt].r);
pushUp(rt);
}
int query(int rt, int L, int R)
{
if(L<=seg[rt].l && seg[rt].r <= R)
return seg[rt].val;
int ans = -1;
int m = (seg[rt].l + seg[rt].r) >> 1;
if(L <= m)
ans = max(ans, query(rt<<1, L, R));
if(R > m)
ans = max(ans, query(rt<<1|1, L, R));
return ans;
}
int main()
{
int n, m, q, t, L, R;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
int tmp;
for(int i=1;i<=n;i++)
{
scanf("%d", &tmp);
a[i] = tmp % m;
}
build(1, 1, n);
scanf("%d", &q);
while(q--)
{
scanf("%d%d", &L, &R);
printf("%d\n", query(1, L, R));
}
}
return 0;
}