bzoj1150/luogu3620 [APIO/CTSC 2007]数据备份 set/链表
如果对于只有2个的情况,那么一定是选最小的和一个不相邻的,或者是选择最小的旁边两个
那么对于k个的情况,我们可以选择一下最小值ai,然后删除左右两边和ai,再加入一个L(zuo)+L(you)-L(p)在新的地方
如果选择了新加入的,那么表示选择了左边和右边的,如果没有选,表示选择了最小值和一个其他的。
用链表+set就可以维护了
1 /* *********************************************** 2 Author :BPM136 3 Created Time :2018/7/16 20:38:00 4 File Name :1150.cpp 5 ************************************************ */ 6 7 #include<iostream> 8 #include<cstdio> 9 #include<algorithm> 10 #include<cstdlib> 11 #include<cmath> 12 #include<cstring> 13 #include<vector> 14 #include<set> 15 using namespace std; 16 17 typedef set<int> SI; 18 typedef vector<int> VI; 19 typedef long long ll; 20 21 const int N = 100005; 22 23 int a[N]; 24 int D[N]; 25 int n,m; 26 27 struct node { 28 node *prev,*next; 29 ll val; 30 }; 31 node *head,*tail; 32 33 void link_list_init() { 34 head=new node(); 35 tail=new node(); 36 head->next=tail; 37 tail->prev=head; 38 } 39 40 node *link_list_insert(node *p,ll val) { 41 node *q=new node(); 42 q->val=val; 43 p->next->prev=q; 44 q->next=p->next; 45 p->next=q; 46 q->prev=p; 47 return q; 48 } 49 50 void link_list_remove(node *p) { 51 p->prev->next=p->next; 52 p->next->prev=p->prev; 53 delete p; 54 } 55 56 void link_list_del() { 57 while(head!=tail) { 58 head=head->next; 59 delete head->prev; 60 } 61 delete tail; 62 } 63 64 struct set_node { 65 ll val; 66 node *p; 67 set_node() {} 68 set_node(node *_p,ll _val) : p(_p), val(_val) {} 69 bool operator<(const set_node &b) const { 70 return val<b.val || (val==b.val && p<b.p); 71 } 72 bool operator==(const set_node &b) const { 73 return p==b.p && val==b.val; 74 } 75 }; 76 77 set< set_node > S; 78 79 int main() { 80 scanf("%d%d",&n,&m); n--; 81 for(int i=1;i<=n+1;i++) scanf("%d",&D[i]); 82 for(int i=1;i<=n;i++) a[i]=D[i+1]-D[i]; 83 link_list_init(); 84 node *last_node=head; 85 for(int i=1;i<=n;i++) { 86 last_node=link_list_insert(last_node, a[i]); 87 S.insert(set_node(last_node, a[i])); 88 } 89 ll ans=0; 90 for(int o=1;o<=m;o++) { 91 auto fi=S.begin(); 92 set_node tmp=*fi; 93 S.erase(fi); 94 ans+=tmp.val; 95 node *p=tmp.p; 96 97 ll new_val=-tmp.val; 98 int flag=0; 99 if(p->prev!=head) { 100 new_val+=p->prev->val; 101 S.erase(S.find(set_node(p->prev, p->prev->val))); 102 link_list_remove(p->prev); 103 flag++; 104 } 105 if(p->next!=tail) { 106 new_val+=p->next->val; 107 S.erase(S.find(set_node(p->next, p->next->val))); 108 link_list_remove(p->next); 109 flag++; 110 } 111 node *pre=p->prev; 112 link_list_remove(p); 113 if(flag==2) { 114 node *q=link_list_insert(pre,new_val); 115 S.insert(set_node(q,new_val)); 116 } 117 } 118 cout<<ans<<endl; 119 return 0; 120 }