COJ 2110 Day7-例3
Day7-例3 |
难度级别:C; 运行时间限制:5000ms; 运行空间限制:256000KB; 代码长度限制:2000000B |
试题描述
|
|
输入
|
输入的第一行包含整数n和k,其中n(2 ≤ n ≤100 000)表示办公楼的数目,k(1≤ k≤ n/2)表示可利用的网络电缆的数目。接下来的n行每行仅包含一个整数(0≤ s ≤1000 000 000), 表示每个办公楼到大街起点处的距离。这些整数将按照从小到大的顺序依次出现。
|
输出
|
输出应由一个正整数组成,给出将2K个相异的办公楼连成k对所需的网络电缆的最小总长度。
|
输入示例
|
5 2
1 3 4 6 12 |
输出示例
|
4
|
题解:奇妙的题。用堆维护每一段,如果取了一个就要把(两边的-这个)放到堆里,表示可以改成选两边的,但是就是不能同时选。
用set实现:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<stack> 6 #include<queue> 7 #include<cstring> 8 #include<set> 9 #define PAU putchar(' ') 10 #define ENT putchar('\n') 11 using namespace std; 12 const int maxn=100000+10; 13 const long long inf=4e18; 14 struct data{long long v;int p;}; 15 bool operator<(const data&a,const data&b){return a.v<b.v||(a.v==b.v&&a.p<b.p);} 16 inline long long read(){ 17 long long x=0,sig=1;char ch=getchar(); 18 for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0; 19 for(;isdigit(ch);ch=getchar())x=10*x+ch-'0'; 20 return sig?x:-x; 21 } 22 inline void write(long long x){ 23 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 24 int len=0;long long buf[20];while(x)buf[len++]=x%10,x/=10; 25 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 26 } 27 set<data>S; 28 long long A[maxn],d[maxn]; 29 int L[maxn],R[maxn],n,k; 30 int main(){ 31 data x;set<data>::iterator t; 32 n=read();k=read(); 33 for(int i=1;i<=n;i++)A[i]=read(); 34 for(int i=1;i<n;i++)d[i]=A[i+1]-A[i];d[0]=inf;d[n]=inf; 35 for(int i=0;i<n;i++)R[i]=i+1,L[i+1]=i; 36 for(int i=0;i<=n;i++)S.insert((data){d[i],i}); 37 long long ans=0; 38 for(int i=1;i<=k;i++){ 39 t=S.begin();x=*t;ans+=x.v; 40 int l=L[x.p],r=R[x.p]; 41 S.erase(t);S.erase((data){d[l],l});S.erase((data){d[r],r}); 42 R[l]=R[r];L[R[r]]=l;d[l]+=d[r]-x.v; 43 S.insert((data){d[l],l}); 44 }write(ans);return 0; 45 }
treap仍然调不对啊。。。为什么。。。我改了重载也过不了啊。。。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<stack> 6 #include<queue> 7 #include<cstring> 8 #include<ctime> 9 #include<set> 10 #define PAU putchar(' ') 11 #define ENT putchar('\n') 12 #define CH for(int d=0;d<2;d++)if(ch[d]) 13 using namespace std; 14 const int maxn=200000+10,maxnode=7000000+10; 15 const long long inf=4e18; 16 struct data{long long v;int p;}; 17 bool operator>(const data&a,const data&b){return a.v>b.v||(a.v==b.v&&a.p>b.p);} 18 bool operator==(const data&a,const data&b){return (a.v==b.v)&&(a.p==b.p);} 19 struct node{ 20 node*ch[2];data v;int siz,r; 21 void init(){siz=1;r=rand();ch[0]=ch[1]=NULL;return;} 22 void update(){siz=1;CH{siz+=ch[d]->siz;}return;} 23 }treap[maxnode],*nodecnt=treap,*root;queue<node*>RM; 24 node*newnode(){node*k;if(RM.empty())k=nodecnt++;else k=RM.front(),RM.pop();k->init();return k;} 25 void del(node*&x){RM.push(x);x=NULL;return;} 26 void rotate(node*&x,int d){ 27 node*k=x->ch[d^1];x->ch[d^1]=k->ch[d];k->ch[d]=x;x->update();k->update();x=k;return; 28 } 29 void insert(node*&x,data v){ 30 if(!x)x=newnode(),x->v=v; 31 else{int d=v>x->v;insert(x->ch[d],v); 32 if(x->r<x->ch[d]->r)rotate(x,d^1);else x->update(); 33 }return; 34 } 35 void remove(node*&x,data v){ 36 if(x->v==v){ 37 if(x->ch[0]&&x->ch[1]){ 38 int d=x->ch[0]->r>x->ch[1]->r;rotate(x,d);remove(x->ch[d],v); 39 }else{node*k=x;x=x->ch[0]?x->ch[0]:x->ch[1];del(k);} 40 }else remove(x->ch[v>x->v],v); 41 if(x)x->update();return; 42 } 43 void print(node*x){ 44 if(!x)return;print(x->ch[0]);printf("%lld ",x->v.v);print(x->ch[1]);return; 45 } 46 data getmi(node*x){ 47 if(x->ch[0])x=x->ch[0];return x->v; 48 } 49 inline long long read(){ 50 long long x=0,sig=1;char ch=getchar(); 51 for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0; 52 for(;isdigit(ch);ch=getchar())x=10*x+ch-'0'; 53 return sig?x:-x; 54 } 55 inline void write(long long x){ 56 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 57 int len=0;long long buf[20];while(x)buf[len++]=x%10,x/=10; 58 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 59 } 60 long long A[maxn],d[maxn]; 61 int L[maxn],R[maxn],n,k; 62 int main(){ 63 srand(time(0)); 64 n=read();k=read(); 65 for(int i=1;i<=n;i++)A[i]=read(); 66 for(int i=1;i<n;i++)d[i]=A[i+1]-A[i];d[0]=inf;d[n]=inf; 67 for(int i=0;i<n;i++)R[i]=i+1,L[i+1]=i; 68 for(int i=0;i<=n;i++)insert(root,(data){d[i],i}); 69 long long ans=0; 70 for(int i=1;i<=k;i++){ 71 data t=getmi(root);ans+=t.v; 72 int l=L[t.p],r=R[t.p]; 73 remove(root,t);remove(root,(data){d[l],l});remove(root,(data){d[r],r}); 74 R[l]=R[r];L[R[r]]=l;d[l]+=d[r]-t.v; 75 insert(root,(data){d[l],l}); 76 }write(ans);return 0; 77 }