zoukankan      html  css  js  c++  java
  • [CTSC2007]数据备份Backup/[国家集训队]种树

    BZOJ

    洛咕

    分析:差分数组A求出相邻两个的差,则问题转化为了:在差分数组A中找k个数,满足k个数之和最小且互不相邻.建立一个小根堆把N-1个点都丢进去。有性质:要么选最小值,要么选最小值旁边两个值。因此先选出最小值的点A[i],用权值为A[i-1]+A[i+1]-A[i]的一个点代替掉原先的这三个点丢进堆即可.

    //#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
    ",ans);
    	return 0;
    }
    
    

    洛咕良心搞了个四倍经验.SP1553多组数据版 记得清空队列和visit数组就好了,代码就不给了.

    种树上面是求最小值,这里只求最大值,所以小根堆变成大根堆即可,代码也不给了.

    [国家集训队]种树线性变环形,给一下代码吧,差别也不太大.

    //#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
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    postman 安装,配置,鉴权
    monkey操作,获取包名,参数,日志,百分比
    monkey环境搭建
    postman接口测试&压力测试
    Fiddler介绍(PC端+Android,IOS端,弱网)
    软件测试的环境搭建
    python2.x- selenium-robot framework自动化测试环境搭建
    SVN的简单操作,版本控制
    svn介绍和安装
    js 函数和函数的参数
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11244511.html
Copyright © 2011-2022 走看看