HDU-4348 - To the moon (主席樹+區間修改)
To the moon
題目連結: To the moon HDU - 4348
題意
給你長度為n的陣列,共有四個操作:
•1.對區間【L,R】增加d,並時間增加1
•2.詢問當前時間的區間【L,R】的和
•3.詢問時間為T時的區間【L,R】的和
•4.返回到時間為T的時候
思路
既然有著時間點的要求也就是歷史版本的要求,那麼主席樹肯定是沒跑的了,奈何我沒有合適的模板,那麼這道題,就是我主席樹的模板了吧。還有但是主席樹的區間的修改,一種辦法是在遇到有延遲更新的區間的時候重新開左右兒子來pushdown 標記,但是這題嚴格一點的資料就能把他卡成空間為n*n*logn。所以還有一種辦法就是,永久化標記,不pushdown,這時候就可以大大節省空間了,nlogn的空間複雜度。
程式碼
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef double db;
typedef long long ll;
const int MAXN = (int)1e5+7;
const int INF = (int)0x3f3f3f3f;
int root[MAXN*10],lc[MAXN*32],rc[MAXN*32],tot;
ll tree[MAXN*32],add[MAXN*32];
int A[MAXN];
void Build(int l,int r,int root){
add[root] = 0;
if(l == r) {
tree[root] = A[l];
return ;
}
int mid = l+r>>1;
Build(l,mid,lc[root]=++tot);
Build(mid+1,r,rc[root]=++tot);
tree[root] = tree[lc[root]] + tree[rc[root]];
}
void Update(int last,int cur,int L,int R,int l,int r,ll d){
tree[cur] = tree[last] + d*(min(R,r)-max(L,l)+1);
lc[cur] = lc[last];
rc[cur] = rc[last];
add[cur] = add[last];
if(L <= l && r <= R) {
add[cur] += d;
return ;
}
int mid = l+r>>1;
if (L <= mid)Update(lc[last],lc[cur]=++tot,L,R,l,mid,d);
if (R > mid)Update(rc[last],rc[cur]=++tot,L,R,mid+1,r,d);
}
ll query(int cur,int L,int R,int l,int r,ll ad){
if(L <= l && r <= R) return tree[cur]+(r-l+1)*ad;
int mid = l+r>>1;
ll ans = 0;
if (L <= mid)ans += query(lc[cur],L,R,l,mid,ad+add[cur]);
if (R > mid)ans += query(rc[cur],L,R,mid+1,r,ad+add[cur]);
return ans;
}
void init() {
tot = 0;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
init();
rep(i,1,n) scanf("%lld",&A[i]);
Build(1,n,root[1]=++tot);
int time = 1;
rep(i,1,m) {
char op[2];int l,r,t;ll k;
scanf("%s",op);
if(op[0] == 'C') {
scanf("%d %d %lld",&l,&r,&k);
time++;
Update(root[time-1],root[time]=++tot,l,r,1,n,k);
}
else if(op[0]=='Q') {
scanf("%d %d",&l,&r);
printf("%lld\n",query(root[time],l,r,1,n,0));
}
else if(op[0]=='H') {
scanf("%d %d %d",&l,&r,&t);
t++;
printf("%lld\n",query(root[t],l,r,1,n,0));
}
else if(op[0]=='B') {
scanf("%d",&t);
time=t+1;
}
}
}
}
相關文章
- 求區間不同數的個數【主席樹求解】
- 芻議線段樹 2 (區間修改,區間查詢)
- 樹狀陣列的區間查詢與區間修改陣列
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列
- 主席樹
- 主席樹模板
- ZeroTier-One配置moon修改埠
- HDU1698 Just a Hook【線段樹基礎:區間修改+區間查詢】Hook
- 靜態主席樹模板
- 動態主席樹模板
- 樹狀陣列模板題 & (樹狀陣列 1:單點修改,區間查詢)陣列
- 線段樹(1)建樹、單點修改、單點查詢、區間查詢和例題
- HDU1754 I Hate It 【線段樹基礎:點修改+區間查詢】
- D-query SPOJ - DQUERY (主席樹)
- HDU2665 Kth number【主席樹】
- HDU4417 Super Mario【主席樹】
- BZOJ4299: Codechef FRBSUM(主席樹)
- 【資料結構】淺談主席樹資料結構
- 洛谷P4197 Peaks(Kruskal重構樹 主席樹)
- HDU1166 敵兵佈陣【線段樹基礎:點修改+區間查詢】
- HDU1166 敵兵佈陣【樹狀陣列 單點修改+區間查詢】陣列
- 【主席數】可持續化線段樹
- SDOI2018 原題識別(主席樹)
- bzoj3524: [Poi2014]Couriers(主席樹)
- 【主席樹】P3919 【模板】可持久化線段樹 1持久化
- 演算法隨筆——主席樹(可持久化線段樹)演算法持久化
- bzoj3545: [ONTAK2010]Peaks(主席樹+最小生成樹)
- bzoj4477: [Jsoi2015]字串樹(主席樹+Hash+Lca)JS字串
- 線段樹 區間乘法加法混合
- HDU 3397 Sequence operation(線段樹區間染色加區間合併)
- bzoj3439: Kpm的MC密碼(主席樹+DFS序+字典樹)密碼
- 線段樹(3)——區間操作疊加
- HDU 2795 Billboard(線段樹 區間最大)
- ubuntu 修改時區或時間 及網路同步時間Ubuntu
- Linux設定和修改時間與時區Linux
- bzoj2809: [Apio2012]dispatching(DFS序+主席樹)API
- bzoj5178: [Jsoi2011]棒棒糖(主席樹)JS
- bzoj1112: [POI2008]磚塊Klo(主席樹)