zoukankan      html  css  js  c++  java
  • 另一个画风的GSS1

    前言

    其实我觉得你看猫锟的解释也看不懂(主要是还有一些不良心的讲解者不讲清楚,当然这里不是针对了qwq)
    猫锟链接

    Solution

    考虑我们的线段树是个啥玩意?
    每一层都是一堆区间叠在一起。
    我们在每一个节点维护的又是什么?
    左边的max,右边的max,中间的max,还有sum。
    那么我们改变一下:
    (p_{dps,i})表示在深度为(dps)的线段树上(i)这个节点所在区间的左边的max,右边的max,然后就可以在(build)的时候求

    再令(p_{dps,i})表示在深度为(dps)的线段树上(i)这个节点所在区间的到中间的(max),然后也可以在(build)的时候求。

    然后就可以(Theta(1))的询问就好了。

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define re register
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    inline int gi()
    {
    	int f=1,sum=0;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    	return f*sum;
    }
    const int N=500010;
    int pos[N],p[21][N],s[21][N],a[N],Log2[N<<3],n;
    void build(int o,int l,int r,int dps)
    {
    	if(l==r)
    	{
    		pos[l]=o;
    		return;
    	}
    	int mid=(l+r)>>1,pre,sm;
    	p[dps][mid]=s[dps][mid]=sm=pre=a[mid];
    	if(sm<0)sm=0;
    	for(int i=mid-1;i>=l;i--)
    	{
    		sm+=a[i];pre+=a[i];
    		s[dps][i]=max(s[dps][i+1],pre);
    		p[dps][i]=max(p[dps][i+1],sm);
    		if(sm<0)sm=0;
    	}
    	p[dps][mid+1]=s[dps][mid+1]=sm=pre=a[mid+1];
    	if(sm<0)sm=0;
    	for(int i=mid+2;i<=r;i++)
    	{
    		sm+=a[i];pre+=a[i];
    		s[dps][i]=max(s[dps][i-1],pre);
    		p[dps][i]=max(p[dps][i-1],sm);
    		if(sm<0)sm=0;
    	}
    	build(o<<1,l,mid,dps+1);
    	build(o<<1|1,mid+1,r,dps+1);
    }
    int query(int l,int r)
    {
    	if(l==r)return a[l];
    	int dps=Log2[pos[l]]-Log2[pos[l]^pos[r]];
    	return max(max(p[dps][l],p[dps][r]),s[dps][l]+s[dps][r]);
    }
    int main()
    {
    	n=gi();
    	for(int i=1;i<=n;i++)a[i]=gi();
    	int L=2;
    	while(L<n)L<<=1;
    	for(int i=2;i<=L<<1;i++)Log2[i]=Log2[i>>1]+1;
    	build(1,1,L,1);
    	int m=gi();
    	while(m--)
    	{
    		int l=gi(),r=gi();
    		printf("%d
    ",query(l,r));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    【反射】Java反射机制
    Composer教程之常用命令
    Composer教程之基础用法
    Composer教程之初识Composer
    Composer 的结构详解
    现代 PHP 新特性系列(七) —— 内置的 HTTP 服务器
    现代 PHP 新特性系列(一) —— 命名空间
    现代 PHP 新特性系列(二) —— 善用接口
    现代 PHP 新特性系列(三) —— Trait 概览
    现代 PHP 新特性系列(四) —— 生成器的创建和使用
  • 原文地址:https://www.cnblogs.com/mleautomaton/p/10268053.html
Copyright © 2011-2022 走看看