OJ2216小奇的数列
Posted farway17
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OJ2216小奇的数列相关的知识,希望对你有一定的参考价值。
2216 -- 小奇的数列(Solution)
题目大意 : 给定一个长度为?(n)?的数列,以及?(m)?次询问,每次给出三个数?(l),(r)?和?(P),询问 ((sum_{i=l_1}^{r_1}a_i);mod;P)?的最小值。 其中 (l le l_1 le r_1 le r) 。 ((nle 5 imes 10^5, mle 10^4,Ple 500))
Tag: 抽屉原理、STL
Analysis By LC:
最朴素的做法当然是计算前缀和再枚举 (l_1) 和 (r_1) 。这里有一个优化:如果区间中有超过 (P) 个元素,那么可以根据抽屉原理证明一定存在一个区间使得区间和膜 (P) 为 (0) ,可以据此让区间大小大于 (P) 的区间直接输出 (0) 。
那么我们只考虑枚举 (l_1) 和 (r_1) 中的一个是否可以完成本题?我们可以只枚举 (r_1) ,显然我们要找到一个 (l_1) ,使得 (s[r_1]-s[l_1]) 最小,即 (s[l_1]) 与 (s[r_1]) 最接近,用STL的 ( ext Set) 即可维护。(这里 (s[x]) 表示 ((sum[x]-sum[l-1]),mod,P) )
Code By LC :
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
inline int _read()
{
char c; int x=0;
for(;c<'0'||c>'9';c=getchar());
for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
return x;
}
typedef long long ll;
const int N=500005;
int a[N];
ll sum[N];
int main()
{
int n=_read(),m=_read();
for(int i=1;i<=n;i++)
{
a[i]=_read();
sum[i]=sum[i-1]+a[i];
}
while(m--)
{
int l=_read(),r=_read(),p=_read(),ans=501;
set<ll> s;
s.insert(0);
if(r-l+1>=p)
{
puts("0");
continue;
}
for(int i=l;i<=r;i++)
{
ll w=(sum[i]-sum[l-1])%p;
auto it=s.upper_bound(w); if(it!=s.begin())--it;
ans=min(ans,int((w-*it)%p));
s.insert(w);
}
printf("%d
",ans);
}
}
以上是关于OJ2216小奇的数列的主要内容,如果未能解决你的问题,请参考以下文章