传送门
会动态开点的话是裸题.不会的话学完就是例题.
动态开点有很多种写法.建议大家根据自己平时写的普通线段树的写法转化成自己的独特写法.说一下开点的问题.
这题离散化可以做但是有点麻烦.动态开点会方便一点,但空间复杂度要很注意才不会爆.我的写法是只存l,r指针不存这个节点表示的l,r区间范围.因为这样子要多开2个空间去存这两个信息,这题的询问有3e5,n在1e9,空间卡的比较死.而且我的懒惰写法会比实际多开一倍的点,所以空间可能不够用,开满了才勉勉强强够用.至于开多大保险.答案是能开多大开多大.
为什么会多开一倍呢,因为不管用到左边的区间还是右边的区间,我都暴力的开两个区间记录,所以一次询问就开了2logn个节点.
线段树的操作部分没什么好讲的,用一个lazy标记记录一下被修改过的值就好了.
我的线段树自带大常数,所以用快读输入了一下,不然tle
代码
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define lson tree[i].ls
#define rson tree[i].rs
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int MAX_N = 1.5e7+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<