分析:計算された差のアレイは、隣接する2つの違いは、問題は、に変換される:配列Kの数の差を見つけ、小さなヒープルートを作成するために、互いに最小の数及び隣接を満たすk個のN-一点に投げます。性質:のいずれかの最小値が選択され、または次の2つの極小値から選択されます。従って最初の正しい値と、最小点を[I]を選択し、[I-1] + [I + 1] -A [i]は以前に反応器に投入3点のうち1点の代わりに、すなわちことができます。
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
const int N=100005;
int a[N],b[N],l[N],r[N],visit[N];
struct node{
int num,val;
bool operator <(const node &x)const{
return val>x.val;
}
}temp;
priority_queue<node>q;
int main(){
int n=read(),k=read();
for(int i=1;i<=n;++i)b[i]=read();
for(int i=1;i<=n-1;++i)a[i]=b[i+1]-b[i];
a[0]=1e9;a[n]=1e9;
for(int i=1;i<=n-1;++i){
temp.num=i;temp.val=a[i];
l[i]=i-1;r[i]=i+1;
q.push(temp);
}
r[0]=1;l[n]=n-1;
int ans=0;
while(k--){
while(visit[q.top().num])q.pop();
temp=q.top();q.pop();
int u=temp.num,v=temp.val;ans+=v;
a[u]=a[l[u]]+a[r[u]]-a[u];temp.val=a[u];
visit[l[u]]=1;visit[r[u]]=1;
l[u]=l[l[u]];r[l[u]]=u;
r[u]=r[r[u]];l[r[u]]=u;
q.push(temp);
}
printf("%d\n",ans);
return 0;
}
ロスクッションの良心は、四重の経験を上演した。データのバージョンのSP1553複数のセットは、キューを空などの配列を訪問し、コードを与えることはありませんことを忘れないでください。
木の最小化上記が小さいことは、スタックする大ルートのルート・スタックとなり、ここで、ちょうど最大値であり、コードが与えられていません。
[ナショナルチーム]植える線形可変ループを、そのためのコードは、違いが大きすぎではありません。
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
const int N=200005;
int a[N],l[N],r[N],visit[N];
struct node{
int num,val;
bool operator <(const node &x)const{
return val<x.val;
}
}temp;
priority_queue<node>q;
int main(){
int n=read(),k=read();if(k>n/2){puts("Error!");return 0;}
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=n;++i){
temp.num=i;temp.val=a[i];
l[i]=i-1;r[i]=i+1;
q.push(temp);
}
l[1]=n;r[n]=1;//差别在这里,保证环形存在
int ans=0;
while(k--){
while(visit[q.top().num])q.pop();
temp=q.top();q.pop();
int u=temp.num,v=temp.val;ans+=v;
a[u]=a[l[u]]+a[r[u]]-a[u];temp.val=a[u];
visit[l[u]]=1;visit[r[u]]=1;
l[u]=l[l[u]];r[l[u]]=u;
r[u]=r[r[u]];l[r[u]]=u;
q.push(temp);
}
printf("%d\n",ans);
return 0;
}