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

    题目

    CF618F Double Knapsack

    思路

    很不错的一个构造题(我不会
    考虑计两个数组\(A,B\)作为前缀和
    \(j\)为满足\(A_i <= B_j\)且最小的值
    由此得出:\(A_i > B_{j - 1}\)
    再得出\(B_j - A_i <= n\)
    \(i\)\(0\)开始计,所以以鸽笼原理,必有\(A_{i1} - B_{j1} = A{i2} - B_{j2}\)
    于是移项 得出答案
    然后就是一些细节上的处理

    代码

    // code by Dix_
    #include<bits/stdc++.h>
    #define ll long long
    
    inline ll read(){
        char C=getchar();
        ll N=0 , F=1;
        while(('0' > C || C > '9') && (C != '-')) C=getchar();
        if(C == '-') F=-1 , C=getchar();
        while('0' <= C && C <= '9') N=(N << 1)+(N << 3)+(C - 48) , C=getchar();
        return F*N;
    }
    
    ll n,a[1000010],b[1000010];
    ll A[1000010],B[1000010];
    
    struct P{
    	ll x,y;
    }QWQ[1000010];
    
    ll num = 0;
    
    ll lb = 0;
    
    int main(){
    	scanf("%lld",&n);
    	for(int i = 1;i <= n;++i){
    		scanf("%lld",&a[i]);
    		A[i] = A[i - 1] + a[i];
    	}
    	for(int i = 1;i <= n;++i){
    		scanf("%lld",&b[i]);
    		B[i] = B[i - 1] + b[i];
    	}
    	bool f = 0;
    	if(B[n] < A[n]){
    		f = 1;
    		std::swap(A,B);
    	}
    	for(int i = 0;i <= n;++i)
    	QWQ[i].x = -1,QWQ[i].y = -1;
    	ll v;
    	for(int i = 0;i <= n;++i){
    		while(B[lb] < A[i] && lb + 1 <= n)
    		lb += 1 ;
    		v = B[lb] - A[i];
    		if(QWQ[v].x == -1)
    			QWQ[v].x = i,QWQ[v].y = lb;
    		else{
    			num = i;
    			break;
    		}
     	}
     	if(f)
     	std::swap(A,B),std::swap(num,lb),std::swap(QWQ[v].x,QWQ[v].y);
    	std::cout<<num - QWQ[v].x<<std::endl;
    	for(int i = QWQ[v].x + 1;i <= num;++i){
    		std::cout<<i<<" ";
    	}
    	puts("");
    	std::cout<<lb - QWQ[v].y<<std::endl;
    	for(int i = QWQ[v].y + 1;i <= lb;++i){
    		std::cout<<i<<" ";
    	}
    }
    
    
  • 相关阅读:
    第二周作业修改+
    第三周作业
    第二周作业修改
    第三次作业
    第二次作业
    获奖感想
    最后的作业
    14周作业
    第七周作业
    第六周作业
  • 原文地址:https://www.cnblogs.com/dixiao/p/14447062.html
Copyright © 2011-2022 走看看