【BZOJ】【1150】【CTSC2007】数据备份Backup

堆/贪心


  一共N-1个元素……用堆维护最大值,取了第x个元素以后,插入v[x-1]+v[x+1]-v[x]这个元素,如果再取这个新元素就表示不取x,而取x-1和x+1……大概就是这种“带反悔”的思路吧……

  已经不会写堆了TAT,膜拜了lyd神犇

 1 /**************************************************************
 2     Problem: 1150
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:428 ms
 7     Memory:3224 kb
 8 ****************************************************************/
 9  
10 //BZOJ 1000
11 #include<cstdio>
12 #include<cstdlib>
13 #include<cstring>
14 #include<iostream>
15 #include<algorithm>
16 #define rep(i,n) for(int i=0;i<n;++i)
17 #define F(i,j,n) for(int i=j;i<=n;++i)
18 #define D(i,j,n) for(int i=j;i>=n;--i)
19 using namespace std;
20  
21 int getint(){
22     int v=0,sign=1; char ch=getchar();
23     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
24     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
25     return v*sign;
26 }
27 typedef long long LL;
28 const int N=100010,INF=~0u>>2;
29 /*******************tamplate********************/
30 int f[N],a[N],pre[N],next[N],v[N];
31 int n,m,ans,p;
32 void up(int p){
33     while(p>1)
34         if(a[f[p]]<a[f[p>>1]]){
35             swap(f[p],f[p>>1]);
36             swap(v[f[p]],v[f[p>>1]]);
37             p>>=1;
38         }
39         else break;
40 }
41 void down(int l,int r){
42     int t=l<<1;
43     while(t<=r){
44         if (t<r && a[f[t]]>a[f[t+1]]) t++;
45         if (a[f[l]]>a[f[t]]){
46             swap(f[l],f[t]);
47             swap(v[f[l]],v[f[t]]);
48             l=t,t=l<<1;
49         }
50         else break;
51     }
52 }
53 void insert(int x){
54     f[++p]=x; v[x]=p;
55     up(p);
56 }
57 void erase(int x){
58     f[v[x]]=f[p]; v[f[p]]=v[x]; p--;
59     up(v[x]); down(v[x],p);
60 }
61 int main(){
62     n=getint(); m=getint();
63     F(i,1,n) a[i]=getint();
64     F(i,1,n-1){
65         a[i]=a[i+1]-a[i],next[i]=i+1,pre[i+1]=i;
66         insert(i);
67     }
68     F(i,1,m){
69         int x=f[1]; ans+=a[x];
70         if(pre[x]==0 && next[x]==n) break;
71         if(pre[x]==0){
72             erase(x),erase(next[x]);
73             pre[next[next[x]]]=0;
74         }else if(next[x]==n){
75             erase(x),erase(pre[x]);
76             next[pre[pre[x]]]=n;
77         }else{
78             erase(x),erase(pre[x]),erase(next[x]);
79             a[x]=a[pre[x]]+a[next[x]]-a[x];
80             insert(x);
81             pre[x]=pre[pre[x]]; next[pre[x]]=x;
82             next[x]=next[next[x]]; pre[next[x]]=x;
83         }
84     }
85     printf("%d\n",ans);
86     return 0;
87 }
88 
View Code
posted @ 2015-03-25 23:26  Tunix  阅读(264)  评论(3编辑  收藏  举报