蒟蒻!!菜菜 求助 玄关
  • 板块学术版
  • 楼主wyf_sinon
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/10/24 22:03
  • 上次更新2023/11/2 11:31:16
查看原帖
蒟蒻!!菜菜 求助 玄关
540177
wyf_sinon楼主2023/10/24 22:03

题意 维护一个数列 长度n<=1e6

1.在[l,r]内连续加上x

2.查询[l,r]内一段长度大于等于2的连续子串 使得子串平均数最大 输出以最简整数比形式 可能小于0(主要是维护

蒟蒻的代码

#include<bits/stdc++.h>
using namespace std;
#define ls pos<<1
#define rs pos<<1|1
const int N=1e6+10;
struct Segment_Tree
{
	int l,r;
	int add,sum;
	int lmx,rmx;
	int size,mx;
	int l_size,r_size;
	int mx_size;
}tree[N*4];
int n,m;
int a[N];
void update(int pos)
{
	tree[pos].sum=tree[ls].sum+tree[rs].sum;
	tree[pos].size=tree[ls].size+tree[rs].size;
	
	if(tree[pos].size==2)
	{
		tree[pos].mx=tree[ls].mx+tree[rs].mx; tree[pos].lmx=tree[pos].mx; tree[pos].rmx=tree[pos].mx;
		tree[pos].mx_size=2; tree[pos].l_size=2; tree[pos].r_size=2;
		return;
	}
	if(tree[pos].size==3)
	{
		int ll=tree[ls].l; int rr=tree[rs].r; 
		if(a[rr]>a[rr-1])
		{
			if(a[ll]<a[rr-1])
			{
				tree[pos].mx=a[rr]+a[rr-1];
				tree[pos].lmx=tree[pos].mx; tree[pos].rmx=tree[pos].mx;
				tree[pos].mx_size=2; tree[pos].l_size=2; tree[pos].r_size=2;
			}
			else
			{
				tree[pos].mx=tree[ls].sum+tree[rs].sum;
				tree[pos].lmx=tree[pos].mx; tree[pos].rmx=tree[pos].mx;
				tree[pos].mx_size=3; tree[pos].l_size=3; tree[pos].r_size=3;
			}
		}
		else
		{
			tree[pos].mx=a[ll]+a[rr-1];
			tree[pos].lmx=tree[pos].mx; tree[pos].rmx=tree[pos].mx;
			tree[pos].mx_size=2; tree[pos].l_size=2; tree[pos].r_size=2;
		}
	}
	if(1.0*tree[ls].lmx/tree[ls].l_size-1.0*(tree[ls].sum+tree[rs].lmx)/(tree[ls].size+tree[rs].l_size)>=1e-9)
	{
		tree[pos].lmx=tree[ls].lmx;tree[pos].l_size=tree[ls].l_size;
	}
	else
	{
		tree[pos].lmx=tree[ls].sum+tree[rs].lmx; tree[pos].l_size=tree[ls].size+tree[rs].l_size;
	}
	
	if(1.0*tree[rs].rmx/tree[rs].r_size-1.0*(tree[rs].sum+tree[ls].rmx)/(tree[rs].size+tree[ls].r_size)>=1e-9)
	{
		tree[pos].rmx=tree[rs].rmx; tree[pos].r_size=tree[rs].r_size;
	}
	else
	{
		tree[pos].rmx=tree[rs].sum+tree[ls].rmx; tree[pos].r_size=tree[rs].size+tree[ls].r_size;
	}
	
	if(1.0*(tree[ls].rmx+tree[rs].lmx)/(tree[ls].r_size+tree[rs].l_size)-1.0*tree[ls].mx/tree[ls].mx_size>=1e-9
	&& 1.0*(tree[ls].rmx+tree[rs].lmx)/(tree[ls].r_size+tree[rs].l_size)-1.0*tree[rs].mx/tree[rs].mx_size>=1e-9 )
	{
		tree[pos].mx=tree[ls].rmx+tree[rs].lmx; tree[pos].mx_size=tree[ls].r_size+tree[rs].l_size;
	}
	else if(1.0*tree[ls].mx/tree[ls].mx_size - 1.0*tree[rs].mx/tree[rs].mx_size>=1e-9 )
	{
		tree[pos].mx=tree[ls].mx; tree[pos].mx_size=tree[ls].mx_size;
	}
	else
	{
		tree[pos].mx=tree[rs].mx; tree[pos].mx_size=tree[rs].mx_size;
	}
	return ;
}
void push_down(int pos)
{
	if(tree[pos].add==0) return;
	
	int c=tree[pos].add;
	tree[pos].add=0;
	
	tree[ls].add+=c;
	tree[ls].sum+=c*(tree[ls].r-tree[ls].l+1);
	tree[ls].lmx+=c*tree[ls].l_size;
	tree[ls].rmx+=c*tree[ls].r_size;
	tree[ls].mx+=c*tree[ls].mx_size;
	
	tree[rs].add+=c;
	tree[rs].sum+=c*(tree[rs].r-tree[rs].l+1);
	tree[rs].lmx+=c*tree[rs].l_size;
	tree[rs].rmx+=c*tree[rs].r_size;
	tree[rs].mx+=c*tree[rs].mx_size;
	
	return;
}

void Build(int pos,int l,int r)
{
	tree[pos].l=l; tree[pos].r=r;
	if(l==r)
	{
		tree[pos].sum=a[l];tree[pos].lmx=a[l];tree[pos].rmx=a[l];tree[pos].mx=a[l];
		tree[pos].l_size=1;tree[pos].r_size=1;tree[pos].mx_size=1;tree[pos].size=1;
		
		return;
	}
	int mid=(l+r)>>1;
	Build(ls,l,mid);
	Build(rs,mid+1,r);
	update(pos);
}

void add(int pos,int l,int r,int c)
{
	if(l<=tree[pos].l&&tree[pos].r<=r)
	{
		tree[pos].add+=c;
		tree[pos].sum+=c*(tree[pos].r-tree[pos].l+1);
		tree[pos].lmx+=c*tree[pos].l_size;
		tree[pos].rmx+=c*tree[pos].r_size;
		tree[pos].mx+=c*tree[pos].mx_size;
		return;
	}
	
	push_down(pos);
	
	int mid=(tree[pos].l+tree[pos].r)>>1;
	
	if(l<=mid) add(ls,l,r,c);
	if(r>mid)  add(rs,l,r,c);
	
	update(pos);
}

Segment_Tree query(int pos,int l,int r)
{
	if(l<=tree[pos].l&&tree[pos].r<=r)
	{
		if(tree[pos].r-tree[pos].l+1==2)
		{
			push_down(pos);
			
			int mid=(tree[pos].l+tree[pos].r)>>1;
			Segment_Tree t,a=query(ls,l,r),b=query(rs,l,r);
			
			t.sum=a.sum+b.sum;
			t.size=a.size+b.size;
			t.mx=a.mx+b.mx; t.mx_size=2; t.l_size=2; t.r_size=2; t.lmx=t.mx; t.rmx=t.mx;
			
			return t;
			
		}
		
		return tree[pos];
	}
	
	push_down(pos);
	int mid=(tree[pos].l+tree[pos].r)>>1;
	if(r<=mid) return query(ls,l,r);
	if(l>mid) return query(rs,l,r);
	
	Segment_Tree t,a=query(ls,l,r),b=query(rs,l,r);
	
	t.sum=a.sum+b.sum;		
	t.size=a.size+b.size;	
	
	if(t.size==2)
	{
		t.mx=a.mx+b.mx;t.l_size=2;t.r_size=2;t.mx_size=2;
		return t; 
	}
	
	if(1.0*a.lmx/a.l_size-1.0*(a.sum+b.lmx)/(a.size+b.l_size)>=1e-9)
	{
		t.lmx=a.lmx;t.l_size=a.l_size;
	}
	else
	{
		t.lmx=a.sum+b.lmx;t.l_size=a.size+b.l_size;
	}
	
	if(1.0*b.rmx/b.r_size-1.0*(b.sum+a.rmx)/(b.size+a.r_size)>=1e-9)
	{
		t.rmx=b.rmx; t.r_size=b.r_size;
	}
	else
	{
		t.rmx=b.sum+a.rmx; t.r_size=b.size+a.r_size;
	}
	
	if( 1.0*(a.rmx+b.lmx)/(a.r_size+b.l_size)-1.0*a.mx/a.mx_size>=1e-9
	&&  1.0*(a.rmx+b.lmx)/(a.r_size+b.l_size)-1.0*b.mx/b.mx_size>=1e-9 )
	{
		t.mx=a.rmx+b.lmx; t.mx_size=a.r_size+b.l_size;
	}
	else if(1.0*a.mx/a.mx_size-1.0*b.mx/b.mx_size>=1e-9)
	{
		t.mx=a.mx; t.mx_size=a.mx_size;
	}
	else
	{
		t.mx=b.mx; t.mx_size=b.mx_size;
	}
	
	return t;
	
}

int gcd(int a,int b)
{
	if(a<b) swap(a,b);
	if(b==0) return a;
	return gcd(b,a%b);
}
int main()
{
//	freopen("ruanmeng1.in","r",stdin);
//	freopen("ruanmeng1.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",a+i);
	Build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int opt,l,r,x;
		scanf("%d%d%d",&opt,&l,&r);
		if(opt==1)
		{
			scanf("%d",&x);
			add(1,l,r,x);
		}
		else
		{
			Segment_Tree ans=query(1,l,r);
			int s=gcd(abs(ans.mx),ans.mx_size);
			if(ans.mx==0) puts("0/1");
			else printf("%d/%d\n",ans.mx/s,ans.mx_size/s);
		}
	}
}

丑陋代码在线求调 还请见谅

可以的话请附上码线段树的心得给MnZn做个参考

机房写了3h没写出来 心态爆炸

2023/10/24 22:03
加载中...