luogu P1438 無聊的數列

2022-03-01 05:37:31 字數 1568 閱讀 7358

區間\(l\)到\(r\)內加等差數列

已知首項為\(k\),公差為\(d\)

那麼每一位加的數值為

\[k+(i-l)*d(l<=i<=r)

\]\[k+i*d-l*d(l<=i<=r)

\]\[k-l*d+i*d(l<=i<=r)

\]我們可以分別加一下\(k-l*d\)和\(i*d\)

前者可以算出來,直接區間加就可以

後者的話,先維護一下\([l,r]\)內的下標和

結合律用一下,加上r*下標和就行了

修改的時候在區間\([l,r]\)內的貢獻為

\[(k-l*d)*(r-l+1)+\sum_^*d

\]

#include #include #include #include #include #include #define ls rt<<1

#define rs rt<<1|1

#define ll long long

#define for(i,a,b) for(int i=a;i<=b;++i)

using namespace std;

const int maxn = 1e5 + 7;

int read()

struct node e[maxn<<2];

int n,m,a[maxn];

void pushup(int rt)

void pushdown(int rt)

if(e[rt].lazy2)

}void build(int l,int r,int rt)

int mid=(e[rt].l+e[rt].r)>>1;

build(l,mid,ls);

build(mid+1,r,rs);

pushup(rt);

e[rt].tot=e[ls].tot+e[rs].tot;

}void modfity_1(int l,int r,ll k,int rt)

pushdown(rt);

int mid=(e[rt].l+e[rt].r)>>1;

if(l<=mid) modfity_1(l,r,k,ls);

if(r>mid) modfity_1(l,r,k,rs);

pushup(rt);

}void modfity_2(int l,int r,ll k,int rt)

pushdown(rt);

int mid=(e[rt].l+e[rt].r)>>1;

if(l<=mid) modfity_2(l,r,k,ls);

if(r>mid) modfity_2(l,r,k,rs);

pushup(rt);

}ll query(int l,int rt)

pushdown(rt);

int mid=(e[rt].l+e[rt].r)>>1;

if(l<=mid) return query(l,ls);

else return query(l,rs);

}int main() else

} return 0;

}

luogu P1438 無聊的數列(線段樹 差分)

題意 對於乙個陣列 a aa 現在有兩個操作 思路 操作一 因為對於乙個區間 l,r l,r l,r 在第 l ll 位上加上 k kk 在區間 l,r l,r l,r 上加上 d dd 再在第 r 1 r 1r 1 位上加上 k r l d k r l d k r l d 這樣對於陣列每一位上的修...

luogu P1438 無聊的數列 差分 線段樹

題目描述 維護乙個數列 a i 支援兩種操作 1 l r k d 給出乙個長度等於 r l 1 的等差數列,首項為 k 公差為 d 並將它對應加到 l,r 範圍中的每乙個數上。即 令 a l a l k,a a k d ldots a r a r k r l times 2 p 詢問序列的第 p 個...

P1438 無聊的數列

板子題 按照ppt所說的,預留0號位和n 1號位,0號位位於2的若干次方的位置。但是我試了一下。沒有嚴格要求的這樣的寫法,這題也能a,資料有點水。include include include include include include include include include inclu...