题意 维护一个数列 长度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没写出来 心态爆炸