luogu3373 模板 線段樹2

2022-06-30 11:27:17 字數 1595 閱讀 5504

題目大意:

已知乙個數列,你需要進行下面三種操作:

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 不是質數,那麼如何處理零散的...