題目大意:
已知乙個數列,你需要進行下面三種操作:
1.將某區間每乙個數乘上x
2.將某區間每乙個數加上x
3.求出某區間每乙個數的和
本線段樹的標記是個二元組:add和mul,其代表將乙個線段中的每乙個點乘以mul再加add。設區間長度為x,原來區間和為sum。如果兩個標記要疊加,標記疊加前區間上的和將是sum*mul+add,疊加後的值將是(sum*mul+add)*mul'+add'=mul*mul'*sum+add*mul'+add'。所以將mul*=mul', add=add*mul'+add'即可。
注意:
#include #include #include using namespace std;const int max_range=100010, max_node = max_range * 4;
#define loop(i, n) for(int i=1; i<=n; i++)
long long p, totrange;
long long orgdata[max_range];
struct rangetree
tag(int m, int a):mul(m),add(a){}
void refresh(tag x)
void clear()
int getsum(int sum, int l, int r)
}; tag _tags[max_node];
long long sum[max_node];
void pushdown(int cur, int l, int r) }
void pullup(int cur)
void update(int cur, int sl, int sr, int al, int ar, int op, int value)
else if (op == 2)
return;
} pushdown(cur, sl, sr);
int mid = (sl + sr) / 2;
if (al <= mid)
update(lson, op, value);
if (ar > mid)
update(rson, op, value);
pullup(cur);
} int query(int cur, int sl, int sr, int al, int ar)
void seteachnode(long long *a, int cur, int l, int r)
int mid = (l + r) / 2;
seteachnode(a, lson);
seteachnode(a, rson);
pullup(cur);
}public:
rangetree() {}
void seteachnode(long long *a)
void update(int l, int r, int op, int value)
long long query(int l, int r)
}g;int main()
} return 0;
}
luogu3373 模板 線段樹 2
題面 已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 題解區間修改 區間查詢。維護兩個lazytag include include using namespace std const int maxn 100010 type...
luogu 3373 模板 線段樹2
如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.將某區間每乙個數乘上x 3.求出某區間每乙個數的和 輸入格式 第一行包含三個整數n m p,分別表示該數列數字的個數 操作的總個數和模數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包...
Luogu3373 模板 線段樹 2
不寫線段樹,就是要分塊!同樣需要打標記 在任何時候,a i mul times a i add bel i 表示 i 屬於哪一塊,a i 表示第 i 個位置的真實值 但是由於標記都是整塊整塊打上去的,無法單點修改,本來可能還可以利用逆元強行修改,問題是 p 571373 不是質數,那麼如何處理零散的...