zoukankan      html  css  js  c++  java
  • CF618F Double Knapsack

    题意简化

    给定两个大小为 n 的集合A,B,要求在每个集合中选出一个子集,使得两个选出来的子集元素和相等
    元素范围在 1~n ,n<=1e5
    题目连接

    题解

    考虑前缀和
    令A集合的前缀和为SA,B的前缀和SB (有点奇怪,但不重要...)
    设SA[n]<SB[n],从0到n枚举i, 对于每个SA[i],找到最小的 SB[j] 使得 SB[j]>=SA[i], 所以(0<=SB[j]-SA[i]<n),
    所以总共会有n+1个 (SB[j]-SA[i]) 而值域却只有n,所以可以保证会有两个及以上重复的数字 (保证有解)
    即:
    存在 (SB[j1]-SA[i1]==SB[j2]-SA[i2])
    显然 B集合中 j2 ~ j1 这段区间的元素和等于A集合中 i2 到 i1 的元素和

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define re register
    #define ll long long
    #define get getchar()
    #define in inline
    in int read()
    {
    	int t=0; char ch=get;
    	while(ch<'0' || ch>'9') ch=get;
    	while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
    	return t;
    }
    const int _=2e6+6;
    int n,a[_],b[_];
    ll suma[_],sumb[_],x[_],y[_];
    bool f[_];
    int main()
    {
    	n=read();
    	for(re int i=1;i<=n;i++)
    		a[i]=read(),suma[i]=suma[i-1]+a[i];
    	for(re int i=1;i<=n;i++)
    		b[i]=read(),sumb[i]=sumb[i-1]+b[i];
    	int fff=0;
    	if(sumb[n]<suma[n]) {
    		for(re int i=1;i<=n;i++) {
    			ll t=a[i];
    			a[i]=b[i],b[i]=t;
    			t=suma[i];
    			suma[i]=sumb[i],sumb[i]=t;
    		}
    		fff=1;
    	}
    	int j=0;
    	for(re int i=0;i<=n;i++) {
    		while(sumb[j]<suma[i]) j++;
    		int k=sumb[j]-suma[i];
    		if(f[k])
    		{
    			if(!fff) {
    				cout<<i-x[k]<<endl;
    				for(re int p=x[k]+1;p<=i;p++)
    					cout<<p<<' ';cout<<endl;
    				cout<<j-y[k]<<endl;
    				for(re int p=y[k]+1;p<=j;p++)
    					cout<<p<<' ';cout<<endl;
    			}
    			else {
    				cout<<j-y[k]<<endl;
    				for(re int p=y[k]+1;p<=j;p++)
    					cout<<p<<' ';cout<<endl;
    				cout<<i-x[k]<<endl;
    				for(re int p=x[k]+1;p<=i;p++)
    					cout<<p<<' ';cout<<endl;
    			}
    			return 0;
    		}
    		f[k]=1;
    		x[k]=i,y[k]=j;
    	}
    }
    
    
  • 相关阅读:
    类和接口的区别
    ref 和out的区别
    重载 重写 多态区别
    UML种类与类的关系
    Window.open() 全攻略
    C#委托
    RT Diagnostics Routines
    tar.bz2 解压命令。
    教你10招最有效防电脑辐射方法
    预处理,编译, 优化, 汇编, 链接
  • 原文地址:https://www.cnblogs.com/yzhx/p/11738152.html
Copyright © 2011-2022 走看看