洛谷P3948 資料結構 題解(差分)

2022-08-03 23:15:18 字數 1632 閱讀 1156

最開始的陣列每個元素都是0

給出n,opt ,min,max,mod 在int範圍內

a: l ,r ,x 表示把[l,r] 這個區間加上x(陣列的從l到r的每個元素都加上x)

q : l ,r 表示詢問[l,r] 這個區間中元素t滿足 min<=(t∗i %mod)<=max 的 t這樣的數的個數(i是陣列下標)(元素的值*陣列下標%mod在min到max範圍內)

由於 edt 請來了一位非三次元的倉鼠,他幫你用延後了部分問題,將這些詢問打入了混亂時空,你的詢問操作》不會超過1000次,不幸的是,對於延後的詢問操作可能有很多次(小於1e7次),但是保證這些延後的詢問操作之後不會再次有修改操作(就是在最後會有很多次詢問,但不會進行修改)

輸入格式:

給出n,opt,mod,min,max表示序列大小,操作次數,取膜,最小值,最大值

下面opt行,給出

a : l ,r ,x 表示區間加,保證x在int範圍內(<2147483647)

q :l ,r 表示區間查詢滿足條件的個數

再給出乙個final 值,表示後面有final 個詢問

下面final 行,給出

l,r 表示詢問區間[l,r]之間滿足條件的個數

輸出格式:

每行對於每個q 操作輸出q 個數表示每次詢問的值,

下面final 行表示final個詢問的值

1.首先因為前半部分以區間修改為主,所以我們採用差分的方法使該操作變為o(1),即對於每個l,r,x,令num[l]+=x,num[r+1]-=x;

2.由於前半部分尋問非常少(小於1000次)每次都計算一遍當前陣列的各個數字,o(n)處理就好;

3.對於final部分的尋問,因為沒有修改,我們考慮離線處理,先進行預處理,用乙個陣列ok[i]記錄i即其以前的元素符合條件的個數,再對於每乙個詢問l,r,輸出ok[r]-ok[l-1]的值即可(因為ok[r]統計的是r及其以前的符合條件的元素個數,減去不在區間[l,r]內的部分,即ok[l-1]就是區間內符合要求的元素個數);

#include#include#include#include#includeusing namespace std;

long long num[100100],n,m,i,j,k,minn,maxn,mod,l,r,x,t,ok[100100];

char c;

inline long long rd()

while(c>='0'&&c<='9')

return f?x:-x;

} inline char getc()

void modify()

void count()

printf("%lld\n",ans);

}int main()

t=rd();

x=0;

for(i=1;i<=n;++i)

for(i=1;i<=t;++i)

return 0;

}

差分陣列的基礎參考以前的隨筆:

洛谷P3948 資料結構 題解

題目傳送 感覺這道題秀了我一地的智商。審題沒審好,沒確定帶修改的操作中詢問的次數 1000,且max和min都是事先給好 不變的。想了半天線段樹 分塊,卻忘了最基礎的暴力。寫不出題時先寫暴力。離線部分 顯然不能暴力處理詢問了,但是沒有修改,又是區間詢問個數,自然要想到字首和優化了。設sum i 為前...

洛谷 P3948 資料結構 (差分陣列)

直接差分陣列搞一搞就ok了。因為前面的查詢和修改摻雜在一起的詢問很少,所以對於那些詢問我們暴力去查詢就ok。在final詢問之前求乙個符合要求的字首和就可以o 1 輸出了。include using namespace std const int maxn 8e4 5 typedef long lo...

洛谷 P3948 資料結構 差分陣列

題目看起來很麻煩,其實就是區間修改和區間查詢,這裡我用的是差分陣列寫的,線段樹應該也可以寫吧,對於剛開始的opt次詢問,可以直接暴力求滿足條件的個數,然後在後面的final次詢問之前我們對差分陣列求乙個字首和,記錄一下所有滿足條件的個數的字首和,然後o 1 去輸出就好了。ac include def...