[洛谷P3948]数据结构
題目大意:有n個(gè)數(shù),opt個(gè)操作,并給你md、min、max。
每種操作有以下兩種:1.給一段區(qū)間加一個(gè)固定值。2.詢問(wèn)一段區(qū)間內(nèi)滿足$min\leq T*i\ mod\ md\leq max$(T是當(dāng)前的數(shù),i是當(dāng)前數(shù)的下標(biāo))的數(shù)的個(gè)數(shù)。
在這opt個(gè)操作里,詢問(wèn)不超過(guò)1000個(gè)。
這之后還有final($<10^7$)個(gè)詢問(wèn)(同上面的詢問(wèn)),保證這些詢問(wèn)中間沒(méi)有修改操作。
要你實(shí)現(xiàn)這些操作。
解題思路:一開(kāi)始被這些巨大的數(shù)據(jù)唬住了,經(jīng)過(guò)思考看了標(biāo)程后突然發(fā)現(xiàn)并不是很難。
對(duì)于區(qū)間和操作,很容易想到差分解決,但中間還有詢問(wèn)操作,怎么辦?
題目說(shuō)中間最多1000個(gè)詢問(wèn),而n最大才80000,對(duì)于每一個(gè)詢問(wèn),都掃描一遍差分?jǐn)?shù)組的話,不考慮常數(shù)則要執(zhí)行大約80000000次操作。
但標(biāo)程告訴我這樣是可以卡過(guò)去的(洛谷神評(píng)測(cè)機(jī))。
再來(lái)考慮后面的詢問(wèn),由于沒(méi)有了修改操作,我們可以維護(hù)一個(gè)前綴和,來(lái)實(shí)現(xiàn)$O(1)$詢問(wèn)。
然后就玄學(xué)地卡了過(guò)去。
C++ Code:
#include<cstdio>
#include<cctype>
#include<cstring>
#define ll long long
int n,opt,mod,min,max,l,r,b[80003];
ll a[80003];
char c;
inline int readint(){
char c=getchar();
bool b=false;
for(;!isdigit(c);c=getchar())b=c=='-';
int d=0;
for(;isdigit(c);c=getchar())
d=(d<<3)+(d<<1)+(c^'0');
return b?-d:d;
}
inline void putint(int p){
if(p==0){
putchar('0');
putchar('\n');
return;
}
int w=1;
while(w<=p)w*=10;w/=10;
while(w){
putchar(p/w+'0');
p%=w;
w/=10;
}
putchar('\n');
}
int main(){
n=readint(),opt=readint(),mod=readint(),min=readint(),max=readint();
memset(a,0,sizeof a);
while(opt--){
for(c=getchar();!isalpha(c);c=getchar());
l=readint(),r=readint();
if(c=='A'){
int num=readint();
a[l]+=num,a[r+1]-=num;
}else{
int cnt=0;
ll sum=0;
for(int i=1;i<=r;++i){
sum+=a[i];
if(i>=l)cnt+=(int)(sum%mod*i%mod>=min&&sum%mod*i%mod<=max);
}
putint(cnt);
}
}
b[0]=0;
ll sum=0;
for(int i=1;i<=n;++i){
sum+=a[i];
b[i]=b[i-1]+(int)(sum%mod*i%mod>=min&&sum%mod*i%mod<=max);
}
for(int final=readint();final--;){
l=readint(),r=readint();
putint(b[r]-b[l-1]);
}
return 0;
}
總結(jié)
以上是生活随笔為你收集整理的[洛谷P3948]数据结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 超声波流量计精度比较的几个原因
- 下一篇: 21-8 数据检索2 top和disti