JZOJ 3992 Chrismas 发表于 2020.08.01 | 分类于 题解 | 10 乐色数据,暴力开 O3 可过可太草了…… Segment Tree Beats 裸题( 代码: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145#include <cstdio>#include <algorithm>#define ls (p << 1)#define rs (ls | 1)using namespace std;const int N = 1e5;int n,m,a[N + 5];struct node{ int min,sec; long long sum,cnt; int tag,add,tag_cnt,add_cnt; int chg_cnt;} seg[(N << 2) + 5];inline void push_add(int p,int tl,int tr,int k,int cnt){ seg[p].sum += (tr - tl + 1LL) * k,seg[p].add += k,seg[p].min += k,seg[p].add_cnt += cnt,seg[p].chg_cnt += (tr - tl + 1LL) * cnt; if(seg[p].sec < 0x3f3f3f3f) seg[p].sec += k; if(seg[p].tag > -0x3f3f3f3f) seg[p].tag += k;}inline void push_max(int p,int k,int cnt){ if(k > seg[p].min) seg[p].sum += (long long)(k - seg[p].min) * seg[p].cnt,seg[p].tag_cnt += cnt,seg[p].chg_cnt += (long long)seg[p].cnt * cnt,seg[p].min = seg[p].tag = k;}inline void push(int p,int tl,int tr){ int mid = tl + tr >> 1; if(seg[p].add_cnt) push_add(ls,tl,mid,seg[p].add,seg[p].add_cnt),push_add(rs,mid + 1,tr,seg[p].add,seg[p].add_cnt), seg[p].add = seg[p].add_cnt = 0; if(seg[p].tag_cnt) push_max(ls,seg[p].tag,seg[p].tag_cnt),push_max(rs,seg[p].tag,seg[p].tag_cnt), seg[p].tag = -0x3f3f3f3f,seg[p].tag_cnt = 0;}void build(int p,int tl,int tr){ seg[p].tag = -0x3f3f3f3f; if(tl == tr) { seg[p].sum = seg[p].min = a[tl],seg[p].sec = 0x3f3f3f3f,seg[p].cnt = 1; return ; } int mid = tl + tr >> 1; build(ls,tl,mid),build(rs,mid + 1,tr); seg[p].sum = seg[ls].sum + seg[rs].sum, seg[p].chg_cnt = seg[ls].chg_cnt + seg[rs].chg_cnt, seg[p].min = min(seg[ls].min,seg[rs].min); if(seg[ls].min == seg[rs].min) seg[p].cnt = seg[ls].cnt + seg[rs].cnt, seg[p].sec = min(seg[ls].sec,seg[rs].sec); else if(seg[ls].min < seg[rs].min) seg[p].cnt = seg[ls].cnt, seg[p].sec = min(seg[ls].sec,seg[rs].min); else seg[p].cnt = seg[rs].cnt, seg[p].sec = min(seg[ls].min,seg[rs].sec);}void update(int l,int r,int k,int p,int tl,int tr){ if(l <= tl && tr <= r) { push_add(p,tl,tr,k,(bool)k); return ; } push(p,tl,tr); int mid = tl + tr >> 1; l <= mid && (update(l,r,k,ls,tl,mid),1); r > mid && (update(l,r,k,rs,mid + 1,tr),1); seg[p].sum = seg[ls].sum + seg[rs].sum, seg[p].chg_cnt = seg[ls].chg_cnt + seg[rs].chg_cnt, seg[p].min = min(seg[ls].min,seg[rs].min); if(seg[ls].min == seg[rs].min) seg[p].cnt = seg[ls].cnt + seg[rs].cnt, seg[p].sec = min(seg[ls].sec,seg[rs].sec); else if(seg[ls].min < seg[rs].min) seg[p].cnt = seg[ls].cnt, seg[p].sec = min(seg[ls].sec,seg[rs].min); else seg[p].cnt = seg[rs].cnt, seg[p].sec = min(seg[ls].min,seg[rs].sec);}void chmax(int l,int r,int k,int p,int tl,int tr){ if(seg[p].min >= k) return ; if(l <= tl && tr <= r && seg[p].sec > k) { push_max(p,k,1); return ; } push(p,tl,tr); int mid = tl + tr >> 1; l <= mid && (chmax(l,r,k,ls,tl,mid),1); r > mid && (chmax(l,r,k,rs,mid + 1,tr),1); seg[p].sum = seg[ls].sum + seg[rs].sum, seg[p].chg_cnt = seg[ls].chg_cnt + seg[rs].chg_cnt, seg[p].min = min(seg[ls].min,seg[rs].min); if(seg[ls].min == seg[rs].min) seg[p].cnt = seg[ls].cnt + seg[rs].cnt, seg[p].sec = min(seg[ls].sec,seg[rs].sec); else if(seg[ls].min < seg[rs].min) seg[p].cnt = seg[ls].cnt, seg[p].sec = min(seg[ls].sec,seg[rs].min); else seg[p].cnt = seg[rs].cnt, seg[p].sec = min(seg[ls].min,seg[rs].sec);}int query(int x,int p,int tl,int tr){ if(tl == tr) return seg[p].sum; push(p,tl,tr); int mid = tl + tr >> 1; return x <= mid ? query(x,ls,tl,mid) : query(x,rs,mid + 1,tr);}int query_cnt(int x,int p,int tl,int tr){ if(tl == tr) return seg[p].chg_cnt; push(p,tl,tr); int mid = tl + tr >> 1; return x <= mid ? query_cnt(x,ls,tl,mid) : query_cnt(x,rs,mid + 1,tr);}int main(){ scanf("%d",&n); for(register int i = 1;i <= n;++i) scanf("%d",a + i); build(1,1,n),scanf("%d",&m); char op; int l,r,k; for(;m;--m) { scanf(" %c%d",&op,&l); if(op == 'A') scanf("%d%d",&r,&k),update(l,r,k,1,1,n); else if(op == 'M') scanf("%d%d",&r,&k),chmax(l,r,k,1,1,n); else printf("%d %d\n",query(l,1,1,n),query_cnt(l,1,1,n)); }} 本文作者: Alpha1022 本文链接: https://www.alpha1022.me/articles/jzoj-3992.htm 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明出处!