Description
上了大学之后,小W和小Z一起报了一门水课,在做作业时遇到了问题。
有一个长度为 n 的数列{ai},为一列树木的美观值。
现在有m 次询问,每次给出三个数l,r和P,
询问对于所有的l <= l’ <= r’ <= r
(a[l’] + a[l’ + 1] + … + a[r’]) mod P的最小值。
Input
第一行为两个正整数n和m,表示数列的长度和询问的个数。
第二行为n个整数,为a[1]~a[n]。
接下来m行,每行三个数l,r和P,代表一次询问。
Output
对于每次询问,输出一行一个整数表示要求的结果
Sample Input
4 2
8 15 9 9
1 3 10
1 4 17
Sample Output
2
1
Data Constraint
对于20%的数据
1 <= n, m <= 1000,1 <= l <= r <= n, 1 <= P <= 100,0 <= a[i] <= 10^9
对于另外的30%的数据
1 <= n, m <= 50000,1 <= l <= r <= n, 1 <= P <= 10,0 <= a[i] <= 10^9
对于100%的数据
1 <= n, m <= 50000, 1 <= l <= r <= n, 1 <= P <= 100, 0 <= a[i] <= 10^9
首先肯定要看出来r-l+1>=p的时候因为抽屉原题必然可以模为0,所以只需要做<=p的
朴素的前缀和是np^2但是好像开个奇怪的桶是可以轻松np的。vis数组记录哪些余数是可得的然后找一个最短的相邻。。。不是很懂那些说乱套数据结构弄出log的人。。桶也算数据结构...?
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#define pb push_back
#define lb lower_bound
#define sqr(x) (x)*(x)
#define lowbit(x) (x)&(-x)
#define Abs(x) ((x) > 0 ? (x) : (-(x)))
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(ll i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1]
#define maxn 500005
#define maxm 100005
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template<class T> inline
void read(T& num){
num = 0; bool f = true;char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') f = false;ch = getchar();}
while(ch >= '0' && ch <= '9') {num = num * 10 + ch - '0';ch = getchar();}
num = f ? num: -num;
}
int out[100];
template<class T> inline
void write(T x,char ch){
if (x==0) {putchar('0'); putchar(ch); return;}
if (x<0) {putchar('-'); x=-x;}
int num=0;
while (x){ out[num++]=(x%10); x=x/10;}
FORM(i,num-1,0) putchar(out[i]+'0'); putchar(ch);
}
/*==================split line==================*/
const double eps=1e-8;
int n, m;
ll a[maxn], vis[1005];
int main(){
read(n); read(m);
FORP(i, 1, n) { read(a[i]); a[i] += a[i - 1];}
FORP(i, 1, m){
ll l, r, p;
read(l); read(r); read(p);
if (r - l + 1 >= p) {puts("0"); continue;}
memset(vis, 0, sizeof(vis));
bool flag = false;
FORP(i, l, r) {
ll temp = (a[i] - a[l - 1]) % p;
if (vis[temp]) {
puts("0"); flag = true; break;
}
vis[temp] = vis[temp + p] = i;
}
if (flag) continue;
ll last = 0, x, ans = INF;
FORP(i, 0, p + p)
if (vis[i]) {
ans = min(ans, i);
if (last == 0){
last = vis[i], x = i;
continue;
}
else {
if (last < vis[i]) ans = min(ans, i - x);
last = vis[i], x = i;
}
}
write(ans,'\n');
}
}
Description
上了大学之后,小W和小Z一起报了一门水课,在做作业时遇到了问题。
有一个长度为 n 的数列{ai},为一列树木的美观值。
现在有m 次询问,每次给出三个数l,r和P,
询问对于所有的l <= l’ <= r’ <= r
(a[l’] + a[l’ + 1] + … + a[r’]) mod P的最小值。
Input
第一行为两个正整数n和m,表示数列的长度和询问的个数。
第二行为n个整数,为a[1]~a[n]。
接下来m行,每行三个数l,r和P,代表一次询问。
Output
对于每次询问,输出一行一个整数表示要求的结果
Sample Input
4 2
8 15 9 9
1 3 10
1 4 17
Sample Output
2
1
Data Constraint
对于20%的数据
1 <= n, m <= 1000,1 <= l <= r <= n, 1 <= P <= 100,0 <= a[i] <= 10^9
对于另外的30%的数据
1 <= n, m <= 50000,1 <= l <= r <= n, 1 <= P <= 10,0 <= a[i] <= 10^9
对于100%的数据
1 <= n, m <= 50000, 1 <= l <= r <= n, 1 <= P <= 100, 0 <= a[i] <= 10^9