1 条题解

  • 0
    @ 2023-2-6 13:20:22

    支持区间加法,查区间最大值,单点修改的线段树。

    #include<cstdio>
    #include<cstring>
    const int N=100005;
    int n,m;
    struct qq
    {
    	int l,r;
    	int s1,s2;
    	int z,z1;
    	int lazy; 
    }s[N*2];
    int num;
    void bt (int l,int r)
    {
    	num++;
    	int a=num;
    	s[a].l=l;s[a].r=r;
    	s[a].s1=s[a].s2=-1;
    	s[a].z=0;
    	s[a].z1=l;
    	s[a].lazy=0;
    	if (l==r) return ;
    	int mid=(l+r)/2;
    	s[a].s1=num+1;bt(l,mid);
    	s[a].s2=num+1;bt(mid+1,r);
    	return ;
    }
    void add (int now,int l,int r,int c)
    {
    	if (s[now].l==s[now].r)
    	{
    		s[now].z+=c;
    		return ;
    	}
    	if (s[now].l==l&&s[now].r==r)
    	{
    		s[now].lazy+=c;
    		s[now].z+=c;
    		return ;
    	}
    	int s1=s[now].s1,s2=s[now].s2;
    	s[s1].lazy+=s[now].lazy;
    	s[s1].z+=s[now].lazy;
    	s[s2].lazy+=s[now].lazy;
    	s[s2].z+=s[now].lazy;
    	s[now].lazy=0;
    	int mid=(s[now].l+s[now].r)/2;
    	if (r<=mid) add(s1,l,r,c);
    	else if (l>mid) add(s2,l,r,c);
    	else
    	{
    		add(s1,l,mid,c);
    		add(s2,mid+1,r,c);
    	}
    	if (s[s1].z>=s[s2].z)
    	{
    		s[now].z=s[s1].z;
    		s[now].z1=s[s1].z1;
    	}
    	else
    	{
    		s[now].z=s[s2].z;
    		s[now].z1=s[s2].z1;
    	}
    	return ;
    }
    int z,z1;
    void find (int now,int l,int r)
    {
    	if (s[now].l==l&&s[now].r==r)
    	{
    		z=s[now].z;
    		z1=s[now].z1;
    		return ;
    	}
    	int s1=s[now].s1,s2=s[now].s2;
    	s[s1].lazy+=s[now].lazy;
    	s[s1].z+=s[now].lazy;
    	s[s2].lazy+=s[now].lazy;
    	s[s2].z+=s[now].lazy;
    	s[now].lazy=0;
    	int mid=(s[now].l+s[now].r)/2;
    	if (r<=mid) find (s1,l,r);
    	else if (l>mid) find (s2,l,r);
    	else
    	{
    		find(s1,l,mid);
    		int a=z,a1=z1;
    		find(s2,mid+1,r);
    		if (a>=z)
    		{
    			z=a;
    			z1=a1;
    		}
    	}
    	return ;
    }
    int main()
    {
    	while (scanf("%d%d",&n,&m))
    	{
    	if (n==0&&m==0) break;
    	num=0;bt(1,n);
    	for (int u=1;u<=m;u++)
    	{
    		char ss[5];
    		scanf("%s",ss);
    		if (ss[0]=='I')	
    		{
    			int a,b,c;
    			scanf("%d%d%d",&a,&b,&c);
    			add(1,a,b,c);
    		}
    		else 
    		{
    			int a,b;
    			scanf("%d%d",&a,&b);
    			find (1,a,b);
    			printf("%d\n",z);
    			add(1,z1,z1,-z);
    		}
    	}
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    22
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者