CF 1420/C2 Pokémon Army (hard version)
老下饭了 从性质想了很久 没想到怎么计算影响
本来想用线段树来维护每个段,大可不必
// by gwt using c++11
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pii;
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define endl '
'
#define count2(x) __builtin_popcount(x)
#define countleadingzero(x) __builtin_clz(x)
#define debug(x) cerr << #x << " = " << x << endl;
inline ll read(){//not solve LLONG_MIN LMAX=9,223,372,036,854,775,807
ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=s*10+ch-'0',ch=getchar();
return s*w;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int T=read();
for(int _=1;_<=T;_++){
int n=read();
int q=read();
vector<int>nums(n+1);
for(int j=1;j<=n;++j)
nums[j]=read();
ll ans=0;
ll sum=0;
vector<int>inclist;
vector<int>poslist;
for(int i=1;i<=n;++i){
if(inclist.empty()){
inclist.pb(nums[i]);
// poslist.pb(i);
}
else if(nums[i]<inclist.back()){
inclist.pb(nums[i]);
// poslist.pb(i);
}
else{
if(inclist[0]-inclist.back()!=0)
sum+=inclist[0]-inclist.back();
inclist.clear();
poslist.clear();
inclist.pb(nums[i]);
poslist.pb(i);
}
}
if(!inclist.empty())
sum+=inclist[0];
if(n==1)
cout<<nums[1]<<endl;
else
cout<<sum<<endl;
for(int i=1;i<=q;++i){
int l=read(),r=read();
if(l==r){//nothing happen
cout<<sum<<endl;
continue;
}
assert(l<r);
//Thinking about posL posR posL-1 posL+1 posR-1 posR+1 six point at all
//erase
ll deta=0;
int t=0;
set<int>needsolve={l-1,l,l+1,r-1,r,r+1};
for(auto t:needsolve){
if(t>0&&t<=n){
int valL=t-1>0?nums[t-1]:-1;
int valR=t+1<=n?nums[t+1]:-1;
if(nums[t]>valL&&nums[t]>valR)deta-=nums[t];
if(nums[t]<valL&&nums[t]<valR)deta+=nums[t];
}
}
//swap
swap(nums[l],nums[r]);
//
//insert
for(auto t:needsolve){
if(t>0&&t<=n){
int valL=t-1>0?nums[t-1]:-1;
int valR=t+1<=n?nums[t+1]:-1;
if(nums[t]>valL&&nums[t]>valR)deta+=nums[t];
if(nums[t]<valL&&nums[t]<valR)deta-=nums[t];
}
}
// debug(deta);
sum+=deta;
cout<<sum<<endl;
}
}
return 0;
}