码迷,mamicode.com
首页 > 其他好文 > 详细

【WZOI 21/239】 Picks loves segment tree

时间:2021-02-22 12:36:23      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:targe   namespace   efi   min   最大   uil   unsigned   --   code   

题链

#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#pragma GCC optimize(2)
using namespace std;
#define LL long long
#define ll long long
#define ULL unsigned long long
#define ls rt<<1
#define rs rt<<1|1
#define MS 500009
#define INF 20000009
#define mod 1000000007
#define Pi acos(-1.0)
#define Pair pair<LL,LL>
#define M 11431471
#define B 231
#define MM 37101101
#define BB 312

LL n,m,k;
LL sum[MS<<2]; // 区间和 
LL maxf[MS<<2]; // 区间最大值 
LL cntf[MS<<2]; // 区间最大值个数 
LL maxse[MS<<2]; // 区间第二大值 
LL lamaxf[MS<<2]; // la_区间最大值需加的数 
LL laoth[MS<<2]; // la_区间非最大值需加的数 

ll read(){
    char c=getchar();ll s=0,f=1;
    for(;!isdigit(c);c=getchar())if(c==‘-‘)f=-1;
    for(;isdigit(c);c=getchar())s=s*10+c-48;
    return s*f;
}

void push_up(int rt){
	sum[rt] = sum[ls] + sum[rs];
	maxf[rt] = max(maxf[ls],maxf[rs]);
	if(maxf[ls] == maxf[rs]){
		cntf[rt] = cntf[ls] + cntf[rs];
		maxse[rt] = max(maxse[ls],maxse[rs]); 
	} 
	else if(maxf[ls] > maxf[rs]){
		cntf[rt] = cntf[ls];
		maxse[rt] = max(maxse[ls],maxf[rs]);
	}
	else{
		cntf[rt] = cntf[rs];
		maxse[rt] = max(maxf[ls],maxse[rs]);
	}
}

void build(int l,int r,int rt){
	lamaxf[rt] = 0;
	laoth[rt] = 0;
	if(l == r){
		LL x;
		x = read();
		sum[rt] = x;
		maxf[rt] = x;
		cntf[rt] = 1;
		maxse[rt] = -1e18;
		return;
	}
	int m = l+r>>1;
	build(l,m,ls);
	build(m+1,r,rs);
	push_up(rt);
}

void update(int rt,int l,int r,LL k1,LL k2){
	sum[rt] += cntf[rt]*k1+(r-l+1-cntf[rt])*k2;
	maxf[rt] += k1;
	if(maxse[rt] != -1e18) maxse[rt] += k2;
	lamaxf[rt] += k1;
	laoth[rt] += k2;
}

void push_down(int rt,int l,int r){
	LL m = l+r>>1;
	LL maxn = max(maxf[ls],maxf[rs]);
	if(maxf[ls] == maxn) update(ls,l,m,lamaxf[rt],laoth[rt]);
	else update(ls,l,m,laoth[rt],laoth[rt]);
	if(maxf[rs] == maxn) update(rs,m+1,r,lamaxf[rt],laoth[rt]);
	else update(rs,m+1,r,laoth[rt],laoth[rt]);
	lamaxf[rt] = laoth[rt] = 0;
}

void update_add(int L,int R,int l,int r,int rt,LL val){
	if(L <= l && r <= R){
		update(rt,l,r,val,val);
		return;
	}
	push_down(rt,l,r);
	int m = l+r>>1;
	if(m >= L) update_add(L,R,l,m,ls,val);
	if(m <  R) update_add(L,R,m+1,r,rs,val);
	push_up(rt);
}

void update_min(int L,int R,int l,int r,int rt,LL val){
	if(maxf[rt] <= val) return;
	if(L <= l && r <= R && val > maxse[rt]){
		update(rt,l,r,val-maxf[rt],0);
		return;
	}
	push_down(rt,l,r);
	int m = l+r>>1;
	if(m >= L) update_min(L,R,l,m,ls,val);
	if(m <  R) update_min(L,R,m+1,r,rs,val);
	push_up(rt);
}

LL get_sum(int L,int R,int l,int r,int rt){
	if(L <= l && r <= R){
		return sum[rt];
	}
	push_down(rt,l,r);
	LL ans = 0;
	int m = l+r>>1;
	if(m >= L) ans += get_sum(L,R,l,m,ls);
	if(m <  R) ans += get_sum(L,R,m+1,r,rs);
	return ans;
}

void solve(){
	n = read() ,m = read();
	build(1,n,1);
	while(m--){
		LL op,l,r,val;
		op = read();
		l = read() ,r = read();
		if(op == 1){
			val = read();
			update_min(l,r,1,n,1,val);
		}
		else if(op == 2){
			val = read();
			update_add(l,r,1,n,1,val);
		} 
		else printf("%lld\n",get_sum(l,r,1,n,1));
	}
}

int main() {
	//ios::sync_with_stdio(false);
	LL te;
	te = 1;
	while(te--){
		solve();
	} 
	
	
	return 0;
}

【WZOI 21/239】 Picks loves segment tree

标签:targe   namespace   efi   min   最大   uil   unsigned   --   code   

原文地址:https://www.cnblogs.com/Tecode/p/14425782.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!