• AW245 你能回答这些问题吗(连续子段和线段树)


    题目地址


    易错点:

    • 建树递归到叶节点后,初始化时要注意不要漏掉某个元素.
    • 查询时要注意不要用反元素名称(rx -> lx).
    • 查询时a和b只需要reset a和b(ans不需要).

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int MAXN=1e6,MAXM=2e5,INF=0x3f3f3f3f,root=1;
    struct Node{
    	int l,r;
    	int s,lx,rx;
    	int ans;
    	void reset(){
    		l=r=s=lx=rx=ans=-INF;
    	}
    }tr[MAXN*4];
    int a[MAXN];
    void build(int p,int l,int r){
    	tr[p].l=l,tr[p].r=r;
    	if(l==r){
    		tr[p].s=tr[p].lx=tr[p].rx=tr[p].ans=a[l];
    		return;
    	}
    	int mid=(tr[p].l+tr[p].r)>>1;
    	build(p<<1,l,mid);
    	build((p<<1)|1,mid+1,r);
    	tr[p].s=tr[p<<1].s+tr[(p<<1)|1].s;
    	tr[p].lx=max(tr[p<<1].lx,tr[p<<1].s+tr[(p<<1)|1].lx);
    	tr[p].rx=max(tr[(p<<1)|1].rx,tr[(p<<1)|1].s+tr[p<<1].rx);
    	tr[p].ans=max(max(tr[p<<1].ans,tr[(p<<1)|1].ans),tr[p<<1].rx+tr[(p<<1)|1].lx);
    }
    void change(int p,int x,int val){
    	if(tr[p].l==tr[p].r){
    		tr[p].s=tr[p].lx=tr[p].rx=tr[p].ans=val;
    		return;
    	}
    	int mid=(tr[p].l+tr[p].r)>>1;
    	if(x<=mid)change(p<<1,x,val);
    	else change((p<<1)|1,x,val);
    	tr[p].s=tr[p<<1].s+tr[(p<<1)|1].s;
    	tr[p].lx=max(tr[p<<1].lx,tr[p<<1].s+tr[(p<<1)|1].lx);
    	tr[p].rx=max(tr[(p<<1)|1].rx,tr[(p<<1)|1].s+tr[p<<1].rx);
    	tr[p].ans=max(max(tr[p<<1].ans,tr[(p<<1)|1].ans),tr[p<<1].rx+tr[(p<<1)|1].lx);
    }
    Node query(int p,int l,int r){
    	if(tr[p].l>=l&&tr[p].r<=r){
    		return tr[p];
    	}
    	int mid=(tr[p].l+tr[p].r)>>1;
    	Node a,b,ans;
    	a.reset(),
    	b.reset();
    	ans.s=0;
    	if(l<=mid){
    		a=query(p<<1,l,r);
    		ans.s+=a.s;
    	}
    	if(r>mid){
    		b=query((p<<1)|1,l,r);
    		ans.s+=b.s;
    	}
    	ans.lx=max(a.lx,a.s+b.lx);
    	ans.rx=max(b.rx,b.s+a.rx);
    	ans.ans=max(max(a.ans,b.ans),a.rx+b.lx);
    	return ans;
    }
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	build(root,1,n);
    	for(int i=1;i<=m;i++){
    		int k,x,y;
    		scanf("%d%d%d",&k,&x,&y);
    		if(k==1){//query
    			if(x>y)swap(x,y);
    			printf("%d
    ",query(root,x,y).ans);
    		}else if(k==2){//change
    			change(root,x,y);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    Distinct Substrings(spoj 694)
    Musical Theme
    Milk Patterns(poj 3261)
    Repeated Substrings(UVAlive 6869)
    喵星球上的点名(bzoj 2754)
    滑雪与时间胶囊(bzoj 2753)
    莫比乌斯函数之和(51nod 1244)
    欧拉函数之和(51nod 1239)
    数表(bzoj 3529)
    欧拉函数模板
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680533.html
Copyright © 2020-2023  润新知