欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Codeforces Round #672 (Div. 2) C2 - Pokémon Army (hard version)(贪心,维护变化值)

程序员文章站 2022-06-05 13:33:59
...

x数组里选一个子数组y(原数组顺序),y1-y2+y3-y4+… 的最大值
然后还有q次交换操作,每次修改之后都要输出新的最大值
Codeforces Round #672 (Div. 2) C2 - Pokémon Army (hard version)(贪心,维护变化值)
(1)如果没有修改,单纯对于当前数组考虑,我们最后选出来的点肯定是波峰波谷这样子,然后最后一个点一定是波峰,并且最后选出来的一定是奇数个
(2)那么最后的答案就是max(0 , a[i] - a[i+1] ) 求和,记得让a[n+1]为0方便统计最后一个波峰 (这里真的妙)
(3)这样的话,对于每个操作,维护一下他的变化就行
(4)不关流会T

#define int ll
int a[MX],ans;

void del(int pos)
{
	if(pos!=1) ans-=max(0ll,a[pos-1]-a[pos]);
	ans-=max(0ll,a[pos]-a[pos+1]);
}
void add(int pos)
{
	if(pos!=1) ans+=max(0ll,a[pos-1]-a[pos]);
	ans+=max(0ll,a[pos]-a[pos+1]);
}
void solve()
{
	int n,q; cin>>n>>q;
	rpp(i,n) cin>>a[i];
	a[0]=a[n+1]=0;
	ans=0;
	for(int i=n;i>=1;--i) ans=ans+max(0ll,a[i]-a[i+1]);
	cout<<ans<<endl;
	while(q--)
	{
		int l,r;cin>>l>>r;
		if(l+1==r) del(l),ans-=max(0ll,a[r]-a[r+1]);
		else del(l),del(r);
		swap(a[l],a[r]);
		if(l+1==r) add(l),ans+=max(0ll,a[r]-a[r+1]);
		else add(l),add(r);
		cout<<ans<<endl;
	}
}
signed main()
{
    fast;
    int T = 1;
    cin>>T;
    while (T--)
    {
        solve();
    }
    stop;
    return 0;
}