區間\(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...