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 }
View Code

 

posted @ 2018-07-17 10:54  My_Girlfriends  阅读(125)  评论(0编辑  收藏  举报