• Codeforces.618F.Double Knapsack(构造 鸽巢原理)


    题目链接


    (Description)

    给定两个大小为(n)的可重集合(A,B),集合中的元素都在([1,n])内。你需要从这两个集合中各选一个非空子集,使它们的和相等。输出方案。
    (nleq10^6)

    (Solution)

    求子集是假的...对两个集合按任意顺序求个前缀和,记为(SA_i,SB_i)。不妨假设(SA_nleq SB_n)
    那么能发现,对于每个(SA_i (0leq ileq n)),找出最大的(SB_jleq SA_i)(j)(SA_i-SB_j)的取值范围是([0,n-1])(如果(geq n)则可以移动(j)),只有(n)种。而(i)的取值有(n+1)种。由鸽巢原理,那么一定存在一对(i,i' (i eq i')),使得(SA_i-SB_j=SA_{i'}-SB_{j'})。因为元素大于(0),所以(j eq j')
    那么有(SA_i-SA_{i'}=SB_j-SB_{j'}),就可以得到答案啦。


    //421ms	23800KB
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define gc() getchar()
    #define MAXIN 500000
    //#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=1e6+5;
    
    LL sa[N],sb[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-48,c=gc());
    	return now;
    }
    void Solve(const int n,LL *sa,LL *sb,int &la,int &ra,int &lb,int &rb)
    {
    	static int vis[N],vis2[N];
    	sb[n+1]=1ll<<60;
    	memset(vis,0xff,sizeof vis);
    	for(int i=0,j=0,v; i<=n; ++i)
    	{
    		while(sb[j+1]<=sa[i]) ++j;
    		if(~vis[v=sa[i]-sb[j]]) {la=vis[v], ra=i, lb=vis2[v], rb=j; break;}
    		vis[v]=i, vis2[v]=j;
    	}
    }
    
    int main()
    {
    	int n=read();
    	for(int i=1; i<=n; ++i) sa[i]=sa[i-1]+read();
    	for(int i=1; i<=n; ++i) sb[i]=sb[i-1]+read();
    	int la,ra,lb,rb;
    	if(sa[n]>sb[n]) Solve(n,sb,sa,lb,rb,la,ra);
    	else Solve(n,sa,sb,la,ra,lb,rb);
    	printf("%d
    ",ra-la);
    	for(int i=la+1; i<=ra; ++i) printf("%d ",i); putchar('
    ');
    	printf("%d
    ",rb-lb);
    	for(int i=lb+1; i<=rb; ++i) printf("%d ",i); putchar('
    ');
    
    	return 0;
    }
    
  • 相关阅读:
    Docker版安装部署 Nexus 及阿里云仓库与本地仓库配置
    Golang开发中如何解决共享变量问题
    什么是dubbo?
    dubbo配置
    redis击穿,穿透,雪崩
    C#根据wsdl文件生成客户端调用代码
    查询哪个程序在使用某个端口
    Java面试题(十六):双亲委派模型
    Java面试题(十五):Java类加载器
    Java面试题(十四):什么是字节码?采用字节码的好处是什么?
  • 原文地址:https://www.cnblogs.com/SovietPower/p/10519255.html
Copyright © 2020-2023  润新知