[CTSC2007]データバックアップバックアップ/ [ナショナルチーム]木

BZOJ

ロス・グー

分析:計算された差のアレイは、隣接する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;
}

おすすめ

転載: www.cnblogs.com/PPXppx/p/11244511.html