假設當前進行到操作 $m$.
1. 將區間 $[l,r]$ 每個數加上 $v$.
2. 詢問當前區間 $[l,r]$ 的和.
3. 令 $s(l,r,x)$ 代表 $[l,r]$ 區間在時刻 $x$ 時之和,求 $\sum_^ s(l,r,i)$.
題解:
對於乙個區間,我們要求當前區間和以及所有歷史時刻之和.
考慮維護 $sum, sumh$ 分別表示當前和以及歷史和.
如果沒有加法標記,我們可以直接存乙個 $tag$,表示 $sumh \leftarrow sumh+tag \times sum.$
然後我們發現存在加法標記的情況下要先下傳加法標記,再下傳 $tag.$
考慮下傳加法標記:
$sum \leftarrow sum+len \times v$
$add \leftarrow add+v$
$sumh \leftarrow sumh+tag \times sum$.
對於點 $x$ 來說,假設原來有 $v1,tag1$,那麼現在變為 $v1+v$,$tag1$.
而根據定義,$tag1$ 應該只和 $v1$ 結合,所有加多了一部分,那麼就再設標記 $addh$ 表示 $sumh$ 需要減去的值就好了.
下傳標記的順序是:$add$,$addh$,$tag$.
code:
#include #include #include #define n 100008#define ll long long
#define lson now<<1
#define rson now<<1|1
#define setio(s) freopen(s".in","r",stdin)
using namespace std;
int a[n],n,m;
struct data s[n];
void pushup(int now)
void mark_adh(int now,ll v,int t)
void mark_add(int now,ll v)
s[now].add+=v;
s[now].sum+=1ll*s[now].len*v;
} void mark_tag(int now,ll v)
void pushdown(int now)
if(s[now].addh)
if(s[now].tag)
}void build(int l,int r,int now)
int mid=(l+r)>>1;
build(l,mid,lson);
build(mid+1,r,rson);
pushup(now);
}void update(int l,int r,int now,int l,int r,int v)
pushdown(now);
int mid=(l+r)>>1;
if(l<=mid) update(l,mid,lson,l,r,v);
if(r>mid) update(mid+1,r,rson,l,r,v);
pushup(now);
}ll query(int l,int r,int now,int l,int r)
pushdown(now);
int mid=(l+r)>>1;
ll re=0;
if(l<=mid) re+=query(l,mid,lson,l,r);
if(r>mid) re+=query(mid+1,r,rson,l,r);
return re;
}
int main()
build(1,n,1);
int x,y,z,l,r;
for(int i=1;i<=m;++i)
return 0;
}
暴力:
#include #define n 1002#define ll long long
#define setio(s) freopen(s".in","r",stdin)
using namespace std;
ll a[n][n],sum[n][n];
int main()
return 0;
}
/*
input:
5 31 2 3 4 5
1 1 1 2 4
1 3 2 2 4
1 3 3 1 5
output:
1831
84
*/
資料生成器及對拍:
#include using namespace std;int ran(int p)
void make()
fprintf(fp,"\n");
for(int i=1;i<=m;++i)
fclose(fp);
}void gen()
int main()
else
}return 0;
}
Arithmetic(線段樹維護歷史版本和)
題意 乙個多重集合的價值為將其變為公差為d dd 將在第一行輸入 的等差數列需要插入幾個數字 無法實現價值為0 多次詢問l,r l,rl,r,求 l,r l,r l,r 的子區間的價值和。序列長度3e5 3e53e 5,數字大小和d 1 e7 d leq 1e7 d 1e7 首先對於r rr r r...
ZKW線段樹 非遞迴版本的線段樹
學習和參考 下面是支援區間修改和區間查詢的zkw線段樹模板,先記下來。include include include include include include include include include include include include include include inc...
線段樹和zkw線段樹
好啦,我們就開始說說線段樹吧 線段樹是個支援區間操作和查詢的東東,平時的話還是蠻實用的 下面以最基本的區間加以及查詢區間和為例 線段樹顧名思義就是棵樹嘛,葉子節點是每個基本點,它們所對應的父親就是它們的和,具體如下圖 但是對於這樣的線段樹來說,操作所需的時間是遠達不到我們的要求的 會被t 因為我們會...