题意:
一个 n n 个数的数组, m m 次操作,操作分三种:
1 x y v: 1 x y v : 对于 i∈[x,y],ai=min(ai,val) i ∈ [ x , y ] , a i = m i n ( a i , v a l )
2 x y: 2 x y : 求 max{ai |i∈[x,y]} m a x { a i | i ∈ [ x , y ] }
3 x y: 3 x y : 求 ∑i=xyai ∑ i = x y a i
思路:
看的论文。哎蒟蒻实在是没这个想法。
然后就是卡我常数卡的比较严重。 要加输入输出挂才能过。
#include
typedef long long ll;
const ll INF = 1e18 + 10;
const int maxn = 1e6 + 10;
using namespace std;
typedef pair pa;
struct Node { ll fmax, smax, lazy, sum, tot; } seg[maxn * 4];
ll rec[maxn], a[10];
void do_it(pa &ans, ll val) {
if(val > ans.first) {
ans.second = ans.first;
ans.first = val;
} else if(val < ans.first && val > ans.second) ans.second = val;
}
pa find_max(int o1, int o2) {
int num = 0;
pa ans(-INF, -INF);
do_it(ans, seg[o1].fmax);
do_it(ans, seg[o2].fmax);
if(seg[o1].smax != -INF) do_it(ans, seg[o1].smax);
if(seg[o2].smax != -INF) do_it(ans, seg[o2].smax);
return ans;
}
void push_up(int o) {
int o1 = o << 1, o2 = o << 1 | 1;
pa fd = find_max(o1, o2);
seg[o].fmax = fd.first;
seg[o].smax = fd.second;
seg[o].sum = seg[o].tot = 0;
if(seg[o].fmax == seg[o1].fmax) seg[o].tot += seg[o1].tot;
if(seg[o].fmax == seg[o2].fmax) seg[o].tot += seg[o2].tot;
seg[o].sum = seg[o1].sum + seg[o2].sum;
}
void build(int o, int l, int r) {
seg[o].lazy = INF;
if(l == r) {
seg[o].fmax = rec[l];
seg[o].smax = -INF;
seg[o].sum = rec[l];
seg[o].tot = 1;
return ;
}
int mid = (l + r) >> 1;
build(o << 1, l, mid);
build(o << 1 | 1, mid + 1, r);
push_up(o);
}
void update_lazy(int o, ll val) {
if(val >= seg[o].fmax) return ;
if(val > seg[o].smax && val < seg[o].fmax) {
seg[o].lazy = min(val, seg[o].lazy);
seg[o].sum += seg[o].tot * (val - seg[o].fmax);
seg[o].fmax = val;
return ;
} else return ;
}
void push_down(int o) {
if(seg[o].lazy == INF) return ;
int o1 = o << 1, o2 = o << 1 | 1;
update_lazy(o1, seg[o].lazy);
update_lazy(o2, seg[o].lazy);
seg[o].lazy = INF;
}
void update(int o, int l, int r, int ql, int qr, ll val) {
if(l > qr || r < ql) return ;
int mid = (l + r) >> 1;
if(l >= ql && r <= qr) {
if(val > seg[o].smax) { update_lazy(o, val); return ; }
else {
push_down(o);
update(o << 1, l, mid, ql, qr, val);
update(o << 1 | 1, mid + 1, r, ql, qr, val);
push_up(o);
}
return ;
}
push_down(o);
update(o << 1, l, mid, ql, qr, val);
update(o << 1 | 1, mid + 1, r, ql, qr, val);
push_up(o);
}
ll query(int o, int l, int r, int ql, int qr, int flag) {
if(l > qr || r < ql) return 0;
if(l >= ql && r <= qr) {
if(flag == 1) return seg[o].sum; ///区间和
if(flag == 0) return seg[o].fmax; ///区间最值
}
int mid = (l + r) >> 1;
push_down(o);
ll p1 = query(o << 1, l, mid, ql, qr, flag);
ll p2 = query(o << 1 | 1, mid + 1, r, ql, qr, flag);
if(flag == 1) return p1 + p2;
else return max(p1, p2);
push_up(o);
}
int n, m, T, kase = 1;
const int MAX = 10000;
char buf[MAX], *ps = buf, *pe = buf + 1;
inline void rnext() {
if(++ps == pe) pe = (ps = buf) + fread(buf, sizeof(char), sizeof(buf) / sizeof(char), stdin);
}
template <class T>
inline bool in(T &ans) {
ans = 0;
T f = 1;
if(ps == pe) return false;//EOF
do{
rnext();
if('-' == *ps) f = -1;
} while(!isdigit(*ps) && ps != pe);
if(ps == pe) return false;//EOF
do {
ans = (ans<<1)+(ans<<3)+*ps-48;
rnext();
} while(isdigit(*ps) && ps != pe);
ans *= f;
return true;
}
///主函数最后调用write()方法
char bufout[MAX], outtmp[50],*pout = bufout, *pend = bufout + MAX;
inline void write() {
fwrite(bufout, sizeof(char), pout - bufout, stdout);
pout = bufout;
}
inline void out_char(char c) { *(pout++) = c; if(pout == pend) write();}
inline void out_str(char *s) {
while(*s) {
*(pout++) = *(s++);
if(pout == pend) write();
}
}
template <class T>
inline void out_int(T x) {
if(!x) {
out_char('0');
return;
}
if(x < 0) x = -x,out_char('-');
int len = 0;
while(x) {
outtmp[len++] = x%10+48;
x /= 10;
}
outtmp[len] = 0;
for(int i = 0, j = len - 1; i < j; i++,j--) swap(outtmp[i],outtmp[j]);
out_str(outtmp);
}
int main() {
in(T);
while(T--) {
in(n); in(m);
for(int i = 0; i < n; i++) in(rec[i]);
build(1, 0, n - 1);
while(m--) {
int op, x, y; ll val;
in(op);
if(!op) {
in(x); in(y); in(val);
update(1, 0, n - 1, x - 1, y - 1, val);
} else {
in(x); in(y);
ll ans = query(1, 0, n - 1, x - 1, y - 1, op - 1);
out_int(ans);
out_char('\n');
}
}
}
write();
return 0;
}