大众分 50分求助!
查看原帖
大众分 50分求助!
153139
风羽跃楼主2022/2/10 16:21

我看好多人都是50->100,有没有做过这题的分享一下经验(#3,4,5,6,7 AC)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>

#define maxn 100005
#define mod
#define INF 0x3f3f3f3f
#define ll long long
#define pii pair<int,int>
#define pdd pair<double,double>
#define esp (1e-8)

using namespace std;

int n,q;
double X[maxn],Y[maxn],f[maxn];

struct Tree{
	double l=0,r=0;
	double len=0;
	double s0,s1,x,y;
	pdd add=make_pair(0,0);
	bool tag;
	#define l(p) tree[p].l
	#define r(p) tree[p].r
	#define s0(p) tree[p].s0
	#define s1(p) tree[p].s1
	#define x(p) tree[p].x
	#define y(p) tree[p].y
	#define add1(p) tree[p].add.first
	#define add2(p) tree[p].add.second
	#define tag(p) tree[p].tag
	#define len(p) tree[p].len
	#define ls (p<<1)
	#define rs (p<<1|1)
}tree[maxn<<2];

void up(int p)
{
	s0(p)=s0(ls)+s0(rs);
	s1(p)=s1(ls)+s1(rs);
	x(p)=x(ls)+x(rs);
	y(p)=y(ls)+y(rs);
}

void down(int p)
{
	if(add1(p)!=0||add2(p)!=0){
		double s=add1(p),t=add2(p);
		
		s0(ls)+=2*x(ls)*s+len(ls)*s*s;
		s1(ls)+=t*x(ls)+s*y(ls)+len(ls)*s*t;
		x(ls)+=len(ls)*s;
		y(ls)+=len(ls)*t;
		add1(ls)+=s;
		add2(ls)+=t;
		
		s0(rs)+=2*x(rs)*s+len(rs)*s*s;
		s1(rs)+=t*x(rs)+s*y(rs)+len(rs)*s*t;
		x(rs)+=len(rs)*s;
		y(rs)+=len(rs)*t;
		add1(rs)+=s;
		add2(rs)+=t;
		
		add1(p)=add2(p)=0;
	}
	
	if(tag(p)){
		s0(ls)=s1(ls)=f[(int)r(ls)]-f[(int)l(ls)-1];
		x(ls)=y(ls)=(l(ls)+r(ls))*len(ls)/2.0;
		add1(ls)=add2(ls)=0;
		tag(ls)=true;
		
		s0(rs)=s1(rs)=f[(int)r(rs)]-f[(int)l(rs)-1];
		x(rs)=y(rs)=(l(rs)+r(rs))*len(rs)/2.0;
		add1(rs)=add2(rs)=0;
		tag(rs)=true;
		
		tag(p)=false;
	}
}

void build(int p,int l,int r)
{
	l(p)=l,r(p)=r,len(p)=r-l+1;
	if(l==r){
		s0(p)=X[l]*X[l];
		s1(p)=X[l]*Y[l];
		x(p)=X[l];
		y(p)=Y[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid),build(rs,mid+1,r);
	up(p);
}

void Add(int p,int l,int r,double s,double t)
{
	if(l<=l(p)&&r>=r(p)){
		add1(p)+=s;
		add2(p)+=t;
		s0(p)+=2*x(p)*s+s*s*len(p);
		s1(p)+=t*x(p)+s*y(p)+len(p)*s*t;
		x(p)+=len(p)*s;
		y(p)+=len(p)*t;
		return ;
	}
	down(p);
	int mid=((int)l(p)+(int)r(p))>>1;
	if(l<=mid) Add(ls,l,r,s,t);
	if(r>mid) Add(rs,l,r,s,t);
	up(p);
}

void change(int p,int l,int r)
{
	if(l<=l(p)&&r>=r(p)){
		s0(p)=s1(p)=f[(int)r(p)]-f[(int)l(p)-1];
		x(p)=y(p)=(l(p)+r(p))*len(p)/2.0;
		add1(p)=add2(p)=0;
		tag(p)=true;
		return ;
	}
	down(p); 
	int mid=((int)l(p)+(int)r(p))>>1;
	if(l<=mid) change(ls,l,r);
	if(r>mid) change(rs,l,r);
	up(p);
}

Tree ask(int p,int l,int r)
{
	if(l<=l(p)&&r>=r(p)) return tree[p];
	down(p);
	int mid=((int)l(p)+(int)r(p))>>1;
	Tree lc,rc,res;
//	cout<<"lc "<<lc.l<<endl;
	if(l<=mid) lc=ask(ls,l,r);
	if(r>mid) rc=ask(rs,l,r);
	if(lc.l==0) return rc;
	if(rc.l==0) return lc;
	res.l=lc.l,res.r=rc.r;
	res.len=lc.len+rc.len;
	res.s0=lc.s0+rc.s0;
	res.s1=lc.s1+rc.s1;
	res.x=lc.x+rc.x;
	res.y=lc.y+rc.y;
	return res;
}

int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}

void write(int x)
{
	if(x>=10) write(x/10);
	putchar(x%10+'0');
}

int qpow(int a,int b,int p)
{
	int res=1;
	while(b){
		if(b&1) res=(ll)res*a%p;
		a=(ll)a*a%p;
		b>>=1;
	}
	return res;
}

//void add_edge(int u,int v)
//{
//	nxt[++cnt]=head[u];
//	to[cnt]=v;
//	head[u]=cnt;
//}

int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	n=read(),q=read();
	for(int i=1;i<=n;i++) scanf("%lf",&X[i]);
	for(int i=1;i<=n;i++) scanf("%lf",&Y[i]);
	for(int i=1;i<=n;i++) f[i]=(double)i*(i+1)*(2.0*i+1)/6.0;
//	cout<<f[i]<<endl;
	build(1,1,n);
	while(q--){
		int op=read(),l=read(),r=read();
		if(op==1){
			Tree a=ask(1,l,r);
			printf("%.10lf\n",(a.len*a.s1-a.x*a.y)/(a.len*a.s0-a.x*a.x));
		}
		if(op==2){
			double s,t;
			scanf("%lf%lf",&s,&t);
			Add(1,l,r,s,t);
		}
		if(op==3){
			double s,t;
			scanf("%lf%lf",&s,&t);
			change(1,l,r);
			Add(1,l,r,s,t);
		}
	}
	//fclose(stdin);
	//fclose(stdout);
	return 0;
}

/*
*/

2022/2/10 16:21
加载中...