记录编号 230804 评测结果 AAAAAAAAAAA
题目名称 快速红包变换 最终得分 100
用户昵称 GravatarKZNS 是否通过 通过
代码语言 C++ 运行时间 2.048 s
提交时间 2016-02-23 21:37:24 内存使用 13.31 MiB
显示代码纯文本
//KZNS
#include <fstream>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
//
ifstream fin ("redbag.in");
ofstream fout ("redbag.out");
const int INF=0x7fffffff;
//
class point {//This class is the type of the Segment Tree
public://If the ID of this point is x, so (x<<1) and (x<<1^1) is left-child and right-child of this point (AKA (x*2) & (x*2+1))
	int l, r;
	int sum;
	int max0, max1, nmax;//max_number in this Segment: max1<max0, number of max0
	int min0, min1, nmin;//min_number in this Segment: min0<min1, number of min0
	int maxc, minc, mc;
	bool cg;
};
class mnn {
public:
	int m0, nm;
};
//
point tree[1<<18];
//
void maketree(int x, int l, int r);
void updata(int x);
void downdata(int x);
void Cadd(int x, int l, int r, int a);
void Cchange(int x, int l, int r, int a);
void Cbmax(int x, int l, int r, int a);
void Cbmin(int x, int l, int r, int a);
int Qsum(int x, int l, int r);
int Qwmax(int x, int l, int r);
int Qwmin(int x, int l, int r);
mnn Qnmax(int x, int l, int r);
mnn Qnmin(int x, int l, int r);
//
int main() {
	int n, m;
	fin >>n;
	maketree(1, 1, n);
	string s;
	int l, r, a;
	fin >>m;
	while (m--) {
		fin >>s >>l >>r;
		if (s=="Cadd") {
			fin >>a;
			Cadd(1, l, r, a);
		} else if (s=="Cchange") {
			fin >>a;
			Cchange(1, l, r, a);
		} else if (s=="Cbmax") {
			fin >>a;
			Cbmax(1, l, r, a);
		} else if (s=="Cbmin") {
			fin >>a;
			Cbmin(1, l, r, a);
		} else if (s=="Qsum") {
			fout <<Qsum(1, l, r) <<endl;
		} else if (s=="Qwmax") {
			fout <<Qwmax(1, l, r) <<endl;
		} else if (s=="Qwmin") {
			fout <<Qwmin(1, l, r) <<endl;
		} else if (s=="Qnmax") {
			mnn uu=Qnmax(1, l, r);
			fout <<uu.nm <<endl;
		} else if (s=="Qnmin") {
			mnn uu=Qnmin(1, l, r);
			fout <<uu.nm <<endl;
		}
	}
	return 0;
}
//
void maketree(int x, int l, int r) {
	point &u=tree[x];
	u.l=l;
	u.r=r;
	u.maxc=0;
	u.minc=0;
	u.mc=0;
	u.cg=false;
	if (l==r) {
		fin >>u.sum;
		u.max0=u.sum;
		u.max1=-INF;
		u.nmax=1;
		u.min0=u.sum;
		u.min1=INF;
		u.nmin=1;
	}
	else {
		maketree(x<<1, l, l+r>>1);
		maketree(x<<1^1, (l+r>>1)+1, r);
		updata(x);
	}
}
void updata(int x) {
	point &u=tree[x], &lc=tree[x<<1], &rc=tree[x<<1^1];
	u.sum=lc.sum+rc.sum;
	//max
	u.nmax=0;
	u.max0=max(lc.max0, rc.max0);
	u.max1=max(lc.max1, rc.max1);
	if (u.max0==lc.max0)
		u.nmax+=lc.nmax;
	else
		u.max1=max(u.max1, lc.max0);
	if (u.max0==rc.max0)
		u.nmax+=rc.nmax;
	else
		u.max1=max(u.max1, rc.max0);
	//min
	u.nmin=0;
	u.min0=min(lc.min0, rc.min0);
	u.min1=min(lc.min1, rc.min1);
	if (u.min0==lc.min0)
		u.nmin+=lc.nmin;
	else
		u.min1=min(u.min1, lc.min0);
	if (u.min0==rc.min0)
		u.nmin+=rc.nmin;
	else
		u.min1=min(u.min1, rc.min0);
}
void downdata(int x) {
	point &u=tree[x];
	if (u.l==u.r) {
		u.maxc=0;
		u.minc=0;
		u.mc=0;
		u.cg=false;
		return;
	}
	point &lc=tree[x<<1], &rc=tree[x<<1^1];
	if (u.cg==true) {
		Cchange(x<<1, u.l, u.r, u.max0);
		Cchange(x<<1^1, u.l, u.r, u.max0);
		u.cg=false;
		return;
	}
	if (!(u.maxc||u.minc||u.mc))
		return;
	if (u.max0==u.min0) {
		Cchange(x<<1, u.l, u.r, u.max0);
		Cchange(x<<1^1, u.l, u.r, u.max0);
		u.maxc=0;
		u.minc=0;
		u.mc=0;
		return;
	}
	Cadd(x<<1, u.l, u.r, u.mc);
	Cadd(x<<1^1, u.l, u.r, u.mc);
	int nm;
	nm=u.max0-u.maxc;
	if (lc.max0==nm)
		Cbmin(x<<1, u.l, u.r, u.max0);
	if (rc.max0==nm)
		Cbmin(x<<1^1, u.l, u.r, u.max0);
	nm=u.min0-u.minc;
	if (lc.min0==nm)
		Cbmax(x<<1, u.l, u.r, u.min0);
	if (rc.min0==nm)
		Cbmax(x<<1^1, u.l, u.r, u.min0);
	u.mc=0;
	u.maxc=0;
	u.minc=0;
}
void Cadd(int x, int l, int r, int a) {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r) {
		if (u.cg==true)
			downdata(x);
		u.mc+=a;
		u.sum+=a*(u.r-u.l+1);
		u.max0+=a;
		if (u.max1!=-INF)
			u.max1+=a;
		u.min0+=a;
		if (u.min1!=INF)
			u.min1+=a;
	} else {
		downdata(x);
		if (l<tree[x<<1^1].l)
			Cadd(x<<1, l, r, a);
		if (tree[x<<1].r<r)
			Cadd(x<<1^1, l, r, a);
		updata(x);
	}
}
void Cchange(int x, int l, int r, int a) {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r) {
		u.cg=true;
		u.mc=0;
		u.maxc=0;
		u.minc=0;
		u.sum=a*(u.r-u.l+1);
		//max
		u.max0=a;
		u.max1=-INF;
		u.nmax=u.r-u.l+1;
		//min
		u.min0=a;
		u.min1=INF;
		u.nmin=u.r-u.l+1;
	} else {
		downdata(x);
		if (l<tree[x<<1^1].l)
			Cchange(x<<1, l, r, a);
		if (tree[x<<1].r<r)
			Cchange(x<<1^1, l, r, a);
		updata(x);
	}
}
void Cbmax(int x, int l, int r, int a) {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r) {
		if (a<=u.min0)
			return;
		else if (u.min0<a&&a<u.min1) {
			if (u.cg==true)
				downdata(x);
			u.sum+=(a-u.min0)*u.nmin;
			if (u.max0==u.min0) {
				u.max0=a;
				u.mc+=a-u.min0;
				u.min0=a;
			}
			else if (u.max1==u.min0) {
				u.max1=a;
				u.minc+=a-u.min0;
				u.min0=a;
			}
			else {
				u.minc+=a-u.min0;
				u.min0=a;
			}
		}
		else {
			downdata(x);
			Cbmax(x<<1, l, r, a);
			Cbmax(x<<1^1, l, r, a);
			updata(x);
		}
	} else {
		downdata(x);
		if (l<tree[x<<1^1].l)
			Cbmax(x<<1, l, r, a);
		if (tree[x<<1].r<r)
			Cbmax(x<<1^1, l, r, a);
		updata(x);
	}
}
void Cbmin(int x, int l, int r, int a) {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r) {
		if (a>=u.max0)
			return;
		else if (u.max0>a&&a>u.max1) {
			if (u.cg==true)
				downdata(x);
			u.sum+=(a-u.max0)*u.nmax;
			if (u.min0==u.max0) {
				u.min0=a;
				u.mc+=a-u.max0;
				u.max0=a;
			}
			else if (u.min1==u.max0) {
				u.min1=a;
				u.maxc+=a-u.max0;
				u.max0=a;
			}
			else {
				u.maxc+=a-u.max0;
				u.max0=a;
			}
		}
		else {
			downdata(x);
			Cbmin(x<<1, l, r, a);
			Cbmin(x<<1^1, l, r, a);
			updata(x);
		}
	} else {
		downdata(x);
		if (l<tree[x<<1^1].l)
			Cbmin(x<<1, l, r, a);
		if (tree[x<<1].r<r)
			Cbmin(x<<1^1, l, r, a);
		updata(x);
	}
}
int Qsum(int x, int l, int r) {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r)
		return u.sum;
	int sum=0;
	downdata(x);
	if (l<tree[x<<1^1].l)
		sum+=Qsum(x<<1, l, r);
	if (tree[x<<1].r<r)
		sum+=Qsum(x<<1^1, l, r);
	return sum;
}
int Qwmax(int x, int l, int r) {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r)
		return u.max0;
	int maax=-INF, uu;
	downdata(x);
	if (l<tree[x<<1^1].l) {
		uu=Qwmax(x<<1, l, r);
		maax=max(maax, uu);
	}
	if (tree[x<<1].r<r){
		uu=Qwmax(x<<1^1, l, r);
		maax=max(maax, uu);
	}
	return maax;
}
int Qwmin(int x, int l, int r) {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r)
		return u.min0;
	int miin=INF, uu;
	downdata(x);
	if (l<tree[x<<1^1].l) {
		uu=Qwmin(x<<1, l, r);
		miin=min(miin, uu);
	}
	if (tree[x<<1].r<r) {
		uu=Qwmin(x<<1^1, l, r);
		miin=min(miin, uu);
	}
	return miin;
}
mnn Qnmax(int x, int l, int r) {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r) {
		mnn ed;
		ed.m0=u.max0;
		ed.nm=u.nmax;
		return ed;
	}
	downdata(x);
	mnn ed;
	ed.m0=-INF;
	ed.nm=0;
	if (l<tree[x<<1^1].l) {
		mnn uu=Qnmax(x<<1, l, r);
		if (ed.m0<uu.m0) {
			ed=uu;
		} else if (ed.m0==uu.m0) {
			ed.nm+=uu.nm;
		}
	}
	if (tree[x<<1].r<r) {
		mnn uu=Qnmax(x<<1^1, l, r);
		if (ed.m0<uu.m0) {
			ed=uu;
		} else if (ed.m0==uu.m0) {
			ed.nm+=uu.nm;
		}
	}
	return ed;
}
mnn Qnmin(int x, int l, int r)  {
	point &u=tree[x];
	if (l<=u.l&&u.r<=r) {
		mnn ed;
		ed.m0=u.min0;
		ed.nm=u.nmin;
		return ed;
	}
	downdata(x);
	mnn ed;
	ed.m0=INF;
	ed.nm=0;
	if (l<tree[x<<1^1].l) {
		mnn uu=Qnmin(x<<1, l, r);
		if (uu.m0<ed.m0) {
			ed=uu;
		} else if (uu.m0==ed.m0) {
			ed.nm+=uu.nm;
		}
	}
	if (tree[x<<1].r<r) {
		mnn uu=Qnmin(x<<1^1, l, r);
		if (uu.m0<ed.m0) {
			ed=uu;
		} else if (uu.m0==ed.m0) {
			ed.nm+=uu.nm;
		}
	}
	return ed;
}
//UBWH