抽屉。



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


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


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值