F. Double Knapsack
time limit per test
2.5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given two multisets A and B. Each multiset has exactly n integers each between 1 and n inclusive. Multisets may contain multiple copies of the same number.

You would like to find a nonempty subset of A and a nonempty subset of B such that the sum of elements in these subsets are equal. Subsets are also multisets, i.e. they can contain elements with equal values.

If no solution exists, print  - 1. Otherwise, print the indices of elements in any such subsets of A and B that have the same sum.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 1 000 000) — the size of both multisets.

The second line contains n integers, denoting the elements of A. Each element will be between 1 and n inclusive.

The third line contains n integers, denoting the elements of B. Each element will be between 1 and n inclusive.

Output

If there is no solution, print a single integer  - 1. Otherwise, your solution should be printed on four lines.

The first line should contain a single integer ka, the size of the corresponding subset of A. The second line should contain ka distinct integers, the indices of the subset of A.

The third line should contain a single integer kb, the size of the corresponding subset of B. The fourth line should contain kb distinct integers, the indices of the subset of B.

Elements in both sets are numbered from 1 to n. If there are multiple possible solutions, print any of them.

Examples
Input
10
10 10 10 10 10 10 10 10 10 10
10 9 8 7 6 5 4 3 2 1
Output
1
2
3
5 8 10
Input
5
4 4 3 3 3
2 2 2 2 5
Output
2
2 3
2
3 5

【参考blog】http://blog.csdn.net/lwt36/article/details/50614772

【题意】给定2个N≤106元素的multiset,元素取值范围为1∼N。现在各从中选出一些元素的subset,subset也是multiset,使得他们的和相等。有解输出各自的大小以及下标,无解输出−1

【分析&&解题思路】参加上面blog,我也不写了,直接放代码吧。

【AC 代码】数据较多,上了读入挂。

//
//Created by just_sort 2016/9/9 18:40
//Copyright (c) 2016 just_sort.All Rights Reserved
//

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
int n,a[maxn],b[maxn];
struct FastIO
{
    static const int S = 1310720;
    int wpos;
    char wbuf[S];
    FastIO() : wpos(0) {}
    inline int xchar()
    {
        static char buf[S];
        static int len = 0, pos = 0;
        if (pos == len)
            pos = 0, len = fread(buf, 1, S, stdin);
        if (pos == len) return -1;
        return buf[pos ++];
    }
    inline int xuint()
    {
        int c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x;
    }
    inline int xint()
    {
        int s = 1, c = xchar(), x = 0;
        while (c <= 32) c = xchar();
        if (c == '-') s = -1, c = xchar();
        for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
        return x * s;
    }
    inline void xstring(char *s)
    {
        int c = xchar();
        while (c <= 32) c = xchar();
        for (; c > 32; c = xchar()) * s++ = c;
        *s = 0;
    }
    inline void wchar(int x)
    {
        if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
        wbuf[wpos ++] = x;
    }
    inline void wint(LL x)
    {
        if (x < 0) wchar('-'), x = -x;
        char s[24];
        int n = 0;
        while (x || !n) s[n ++] = '0' + x % 10, x /= 10;
        while (n--) wchar(s[n]);
    }
    inline void wstring(const char *s)
    {
        while (*s) wchar(*s++);
    }
    ~FastIO()
    {
        if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
    }
} io;
int main()
{
    LL sum1,sum2;
    bool ok=0;
    n = io.xint();
    sum1 = sum2 = 0;
    for(int i=1; i<=n; i++) a[i] = io.xint();
    for(int i=1; i<=n; i++) b[i] = io.xint();
    for(int i=1; i<=n; i++) sum1 += a[i];
    for(int i=1; i<=n; i++) sum2 += b[i];
    //cout<<sum1<<" "<<sum2<<endl;
    if(sum1>sum2) swap(a,b) , ok = 1;
    vector<pair<int,int> >vs(n);
    vector<int>ans1;
    vector<int>ans2;
    for(auto &x : vs) x = {-1,-1};
    vs[0] = {1,1};
    LL xs = 0, ys = 0;
    for(int i = 1,j = 1; i <= n; ){
        xs += a[i++];
        while(j<=n && ys+b[j] <= xs) ys += b[j++];
        int dif = xs - ys;
        if(~vs[dif].first)
        {
            for(int k = vs[dif].first; k<i; k++) ans1.push_back(k);
            for(int k = vs[dif].second; k<j; k++) ans2.push_back(k);
            break;
        }
        vs[dif] = {i,j};
    }
    if(ok) swap(ans1,ans2);
    printf("%d\n",ans1.size());
    for(int i=0; i<ans1.size(); i++){
        printf("%d%c",ans1[i]," \n"[i==ans1.size()-1]);
    }
    printf("%d\n",ans2.size());
    for(int i=0; i<ans2.size(); i++){
        printf("%d%c",ans2[i]," \n"[i==ans2.size()-1]);
    }
}