bzoj1798 ahoi2009 維護序列

2021-07-05 21:48:40 字數 2365 閱讀 5102

time limit: 30 sec  

memory limit: 64 mb

submit: 3714  

solved: 1364 [

submit][

status][

discuss]

老師交給小可可乙個維護數列的任務,現在小可可希望你來幫他完成。 有長為n的數列,不妨設為a1,a2,…,an 。有如下三種操作形式: (1)把數列中的一段數全部乘乙個值; (2)把數列中的一段數全部加乙個值; (3)詢問數列中的一段數的和,由於答案可能很大,你只需輸出這個數模p的值。

第一行兩個整數n和p(1≤p≤1000000000)。第二行含有n個非負整數,從左到右依次為a1,a2,…,an, (0≤ai≤1000000000,1≤i≤n)。第三行有乙個整數m,表示操作總數。從第四行開始每行描述乙個操作,輸入的操作有以下三種形式: 操作1:「1 t g c」(不含雙引號)。表示把所有滿足t≤i≤g的ai改為ai×c (1≤t≤g≤n,0≤c≤1000000000)。 操作2:「2 t g c」(不含雙引號)。表示把所有滿足t≤i≤g的ai改為ai+c (1≤t≤g≤n,0≤c≤1000000000)。 操作3:「3 t g」(不含雙引號)。詢問所有滿足t≤i≤g的ai的和模p的值 (1≤t≤g≤n)。 同一行相鄰兩數之間用乙個空格隔開,每行開頭和末尾沒有多餘空格。

對每個操作3,按照它在輸入中出現的順序,依次輸出一行乙個整數表示詢問結果。

7 43

1 2 3 4 5 6 7

51 2 5 5

3 2 4

2 3 7 9

3 1 3

3 4 7235

8【樣例說明】

初始時數列為(1,2,3,4,5,6,7)。

經過第1次操作後,數列為(1,10,15,20,25,6,7)。

對第2次操作,和為10+15+20=45,模43的結果是2。

經過第3次操作後,數列為(1,10,24,29,34,15,16}

對第4次操作,和為1+10+24=35,模43的結果是35。

對第5次操作,和為29+34+15+16=94,模43的結果是8。

測試資料規模如下表所示

資料編號 1 2 3 4 5 6 7 8 9 10

n= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

m= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

day1

線段樹中使用乘法和加法兩種標記。加法操作和詢問操作不變,乘法操作每次要把加法標記和區間和都乘上相應的數,下傳標記時先下傳乘法標記再下傳加法標記。

#include#include#include#include#include#define f(i,j,n) for(int i=j;i<=n;i++)

#define d(i,j,n) for(int i=j;i>=n;i--)

#define ll long long

#define maxn 100005

using namespace std;

struct tree_type

t[maxn*4];

int n,m,p,opt,l,r,c,a[maxn];

void build(int num,int l,int r)

int mid=(l+r)/2;

build(num*2,l,mid);

build(num*2+1,mid+1,r);

t[num].sum=(t[num*2].sum+t[num*2+1].sum)%p;

return;

}void push_down(int num)

void add(int num,int l,int r,int x)

push_down(num);

add(num*2,l,r,x);

add(num*2+1,l,r,x);

t[num].sum=(t[num*2].sum+t[num*2+1].sum)%p;

return;

}void multiply(int num,int l,int r,int x)

push_down(num);

multiply(num*2,l,r,x);

multiply(num*2+1,l,r,x);

t[num].sum=(t[num*2].sum+t[num*2+1].sum)%p;

return;

}ll ask(int num,int l,int r)

int main()

if (opt==2)

if (opt==3)

}return 0;

}

BZOJ 1798 維護序列

線段樹 這 d 道 q 題 s 告訴我說 你沒學過線段樹 嗯 這題要好好想想 qaq 來吧首先要明確的事情是 delta now 記錄的是已經對當前點做過的,但是還沒有對當前點的兒子做過的操作 嗯 我們就這樣 慢慢的退一下 嗯 標記是給兒子用的 嗯 是給兒子用的 奉獻精神 然後,對於這個題,我們可以...

BZOJ 1798, 維護序列

傳送門 維護乙個數列,要求支援區間加 區間乘以及查詢操作。很裸的線段樹,難點在於加法和乘法的操作順序。標記下傳時應先打乘法標記,再打加法標記,同時更新時還要用乘法標記維護加法標記。include typedef long long ll const int n 100005 int n,p,m,x,...

bzoj 1798 線段樹 雙lazy標記

time limit 30 sec memory limit 64 mb submit 2645 solved 984 submit status 老師交給小可可乙個維護數列的任務,現在小可可希望你來幫他完成。有長為n的數列,不妨設為a1,a2,an 有如下三種操作形式 1 把數列中的一段數全部乘乙...