RT,这道题是P3620的一个多倍经验题。但是在这个题里面如果不勾选C++11,只选择C++,会CE。本地便衣C++98和C++03都是没问题的。原题P3620也没问题,但是这道题如果不勾选C++11,只勾选C++就会CE。 代码如下:
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e5+5;
using namespace std;
void readll(ll &res){
res = 0;ll f = 1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
f *= -1;
}
ch = getchar();
}
while(ch>='0'&&ch<='9'){
res = res*10+ch-'0';
ch = getchar();
}
res *= f;
return;
}
ll N,K;
ll ora[MAXN];
struct seg{
ll l,r,val;
}segs[MAXN<<1];
struct node{
ll val,idx;
bool operator<(const node&n)const{
return val>n.val;
}
};
priority_queue<node> q;
bool vis[MAXN<<1];
void del(int x){
segs[x].l = segs[segs[x].l].l;
segs[x].r = segs[segs[x].r].r;
segs[segs[x].l].r = x;
segs[segs[x].r].l = x;
return;
}
ll ans;
ll T;
int main(){
readll(T);
while(T--){
memset(segs,0,sizeof(segs));
ans = 0;
while(!q.empty()){
q.pop();
}
for(int i = 0;i<=N+1;++i){
vis[i]=false;
}
readll(N);readll(K);
for(int i = 1;i<=N;++i){
readll(ora[i]);
if(i!=1){
segs[i].val=ora[i]-ora[i-1];
segs[i].l = i-1;
segs[i].r = i+1;
node nv;
nv.val =segs[i].val;nv.idx= i;
q.push(nv);
}
}
segs[1].val=segs[N+1].val = INF;
for(int i = 1;i<=K;++i){
node nu;
while(!q.empty()){
nu = q.top();
q.pop();
if(!vis[nu.idx]){
break;
}
}
ans+=nu.val;
vis[segs[nu.idx].l]=vis[segs[nu.idx].r]=true;
segs[nu.idx].val = segs[segs[nu.idx].l].val + segs[segs[nu.idx].r].val -nu.val;
node nv;nv.val = segs[nu.idx].val;nv.idx = nu.idx;
q.push(nv);
del(nu.idx);
}
printf("%lld\n",ans);
}
return 0;
}