HDU - 5316 Magician(线段树区间合并)

题目链接:点击查看

题目大意:给出长度为 n 的数列 a ,接下来进行 m 次操作,每次操作分为两种类型:

  1. 0 l r:询问区间 [ l , r ] 内的最长子序列之和,要求相邻两个位置的下标奇偶性不同
  2. 1 pos val:修改 pos 位置的数字为 val

题目分析:需要用到区间合并,因为下标奇偶性不同,所以在合并的时候,一共只有四种情况:奇奇,奇偶,偶奇,偶偶,直接分情况维护最大值就好了

代码:
 

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;

typedef long long LL;

typedef unsigned long long ull;

const LL inf=0x3f3f3f3f3f3f3f3f;

const int N=1e5+100;

struct Node
{
	int l,r;
	LL oo,jj,oj,jo;
}tree[N<<2];

void pushup(int k)
{
	Node &a=tree[k<<1],&b=tree[k<<1|1];
	tree[k].jj=max(max(a.jj,b.jj),max(a.jj+b.oj,a.jo+b.jj));
	tree[k].oo=max(max(a.oo,b.oo),max(a.oo+b.jo,a.oj+b.oo));
	tree[k].jo=max(max(a.jo,b.jo),max(a.jj+b.oo,a.jo+b.jo));
	tree[k].oj=max(max(a.oj,b.oj),max(a.oo+b.jj,a.oj+b.oj));
}

void init(int k,LL val,int pos)
{
	tree[k].oo=tree[k].jj=tree[k].oj=tree[k].jo=-inf;
	if(pos&1)
		tree[k].jj=val;
	else
		tree[k].oo=val;
}

void build(int k,int l,int r)
{
	tree[k].l=l;
	tree[k].r=r;
	if(l==r)
	{
		LL val;
		scanf("%lld",&val);
		init(k,val,l);
		return;
	}
	int mid=l+r>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	pushup(k);
}

void change(int k,int pos,LL val)
{
	if(tree[k].l==tree[k].r)
	{
		init(k,val,tree[k].l);
		return;
	}
	int mid=tree[k].l+tree[k].r>>1;
	if(pos<=mid)
		change(k<<1,pos,val);
	else
		change(k<<1|1,pos,val);
	pushup(k);
}

Node query(int k,int l,int r)
{
	if(tree[k].l>=l&&tree[k].r<=r)
		return tree[k];
	int mid=tree[k].l+tree[k].r>>1;
	if(r<=mid)
		return query(k<<1,l,r);
	else if(l>mid)
		return query(k<<1|1,l,r);
	else
	{
		Node a=query(k<<1,l,r),b=query(k<<1|1,l,r),ans;
		ans.jj=max(max(a.jj,b.jj),max(a.jj+b.oj,a.jo+b.jj));
		ans.oo=max(max(a.oo,b.oo),max(a.oo+b.jo,a.oj+b.oo));
		ans.jo=max(max(a.jo,b.jo),max(a.jj+b.oo,a.jo+b.jo));
		ans.oj=max(max(a.oj,b.oj),max(a.oo+b.jj,a.oj+b.oj));
		return ans;
	}
}

int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
	int w;
	cin>>w;
	while(w--)
	{
		int n,m;
		scanf("%d%d",&n,&m);
		build(1,1,n);
		while(m--)
		{
			int op;
			scanf("%d",&op);
			if(op==1)
			{
				int pos;
				LL val;
				scanf("%d%lld",&pos,&val);
				change(1,pos,val);
			}
			else if(op==0)
			{
				int l,r;
				scanf("%d%d",&l,&r);
				Node t=query(1,l,r);
				printf("%lld\n",max(max(t.jj,t.oo),max(t.oj,t.jo)));
			}
		}
	}

























    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/106951729