好像是push写错了,但我太菜,不知道错在哪了。
调样例一时答案随机改变。。
// code by aier
// think twice,code once!
#include <bits/stdc++.h>
#define AC return 0;
using namespace std;
const int maxn = 1e5 + 10;
int n, m;
int a[maxn];
char getc()
{
static char buf[maxn << 3], *s, *t;
return (s == t) && (t = (s = buf) + fread(buf, 1, maxn << 3, stdin)), (s == t) ? EOF : *s++;
}
void read(int &x)
{
x = 0;
bool f = 0;
char ch = getc();
while (!isdigit(ch))
{
if (ch == '-')
f = 1;
ch = getc();
}
while (isdigit(ch))
{
x = x * 10 + ch - '0';
ch = getc();
}
f ? x = -x : 0;
}
mt19937 mt(time(NULL));
struct treap
{
struct node
{
int ls, rs;
int siz, val, len;
int sum, tagl, tagk;
int pri;
node() : ls(0), rs(0), siz(0), val(0), len(0), tagl(0), tagk(0) {}
node(int val, int len = 1) : siz(1), len(len), val(val), pri(mt()), sum(val * len), ls(0), rs(0), tagl(0), tagk(0) {}
} t[maxn << 2];
int rt, cnt;
#define ls(u) t[u].ls
#define rs(u) t[u].rs
#define siz(u) t[u].siz
#define val(u) t[u].val
#define tagl(u) t[u].tagl
#define tagk(u) t[u].tagk
#define pri(u) t[u].pri
#define sum(u) t[u].sum
#define len(u) t[u].len
int new_node(int val, int len = 1)
{
t[++cnt] = node(val, len);
return cnt;
}
void push_up(int u)
{
siz(u) = siz(ls(u)) + siz(rs(u)) + len(u);
sum(u) = sum(ls(u)) + sum(rs(u)) + val(u) * len(u);
}
int bulid(int l, int r)
{
if (l > r)
return 0;
int mid = (l + r) >> 1;
int u = new_node(a[mid]);
ls(u) = bulid(l, mid - 1);
rs(u) = bulid(mid + 1, r);
push_up(u);
return u;
}
void bulid()
{
rt = bulid(1, n);
}
// l: 每一项额外加的值
// k: 后续每一项加的值
void addtag(int u, int l, int k)
{
if (!u)
return;
sum(u) += siz(u) * l + ((siz(u) * (siz(u) + 1)) >> 1) * k;
tagl(u) += l;
tagk(u) += k;
val(u) += l + (siz(ls(u)) + 1) * k;
}
void push_down(int u)
{
if (tagk(u) && tagl(u))
{
if (ls(u))
addtag(ls(u), tagl(u), tagk(u));
if (rs(u))
addtag(rs(u), tagl(u) + (siz(ls(u)) + len(u)) * tagk(u), tagk(u));
tagk(u) = tagl(u) = 0;
}
}
int merge(int l, int r)
{
if (!l || !r)
return l + r;
if (pri(l) < pri(r))
{
push_down(l);
rs(l) = merge(rs(l), r);
push_up(l);
return l;
}
else
{
push_down(r);
ls(r) = merge(l, ls(r));
push_up(r);
return r;
}
}
// 返回值分为三部分
// l:siz<=x r:siz<siz(u)-x
// 返回len跨过x的节点(如果有)
int split(int u, int x, int &l, int &r)
{
if (!u)
{
l = r = 0;
return 0;
}
push_down(u);
if (siz(ls(u)) + len(u) < x)
{
l = u;
int tmp = split(rs(u), x - siz(ls(u)) - len(u), rs(u), r);
push_up(u);
return tmp;
}
else if (siz(ls(u)) > x)
{
r = u;
int tmp = split(ls(u), x, l, ls(u));
push_up(u);
return tmp;
}
else
{
int tmp = 0;
if (siz(ls(u)) + len(u) == x)
{
l = u;
r = rs(u);
rs(u) = 0;
}
else if (siz(ls(u)) == x)
{
r = u;
l = ls(u);
ls(u) = 0;
}
else
{
l = ls(u);
r = rs(u);
ls(u) = rs(u) = 0;
tmp = u;
}
push_up(u);
return tmp;
}
}
// siz(l)=x
// siz(r)=siz(rt)-x
void split_(int u, int x, int &l, int &r)
{
int tmp = split(u, x, l, r);
if (tmp)
{
x -= siz(l);
int _ = new_node(val(tmp), len(tmp) - x);
len(tmp) = x;
push_up(tmp);
l = merge(l, tmp);
r = merge(_, r);
}
}
void assign(int l, int r, int k)
{
int l_, r_, p;
split_(rt, l - 1, l_, p);
split_(p, r - l + 1, p, r_);
rt = merge(l_, merge(new_node(k, siz(p)), r_));
}
void add(int l, int r, int k)
{
int l_, r_, p;
split_(rt, l - 1, l_, p);
split_(p, r - l + 1, p, r_);
addtag(p, 0, k);
rt = merge(l_, merge(p, r_));
}
void insert(int pos, int val)
{
int l, r;
split_(rt, pos - 1, l, r);
rt = merge(l, merge(new_node(val), r));
}
int query(int l, int r)
{
int l_, r_, p;
split_(rt, l - 1, l_, p);
split_(p, r - l + 1, p, r_);
int res = sum(p);
rt = merge(l_, merge(p, r_));
return res;
}
};
treap t;
void solve()
{
while (m--)
{
int opt, l, r, k;
read(opt);
switch (opt)
{
case 1:
read(l);
read(r);
read(k);
t.assign(l, r, k);
break;
case 2:
read(l);
read(r);
read(k);
t.add(l, r, k);
break;
case 3:
read(l);
read(k);
t.insert(l, k);
break;
case 4:
read(l);
read(r);
printf("%d\n", t.query(l, r));
break;
}
}
}
void init()
{
read(n);
read(m);
for (int i = 1; i <= n; ++i)
read(a[i]);
t.bulid();
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
init();
solve();
AC
}
帮帮萌新吧