Description
Catly有k个序列,每个序列有ni个元素,Catly想知道是否在k个序列中有两个序列,p和q,只要删除p中一个元素和q中一个元素,能使得q中元素和等于q中元素和
Input
第一行一个k(2<=k<=2e5) 代表有k个序列 接下来有2*k行,一行为ni(1<=ni<=2e5)代表第i个序列有多少个元素,数据保证k<=n1+...+nk<=2e5 下面一行有ni个数字aj(-10000<=aj<=10000)代表第i个序列中的元素
Output
如果有输出YES,并输出是哪两个序列x,y(x<y,x最小),若有多组解输出序列号y+x最小的一对,否则输出NO 2023.9.24 _Yuu修改:若有多解请输出以x+y为第一依据升序,以x为第二依据降序的第一个
Sample Input
2 5 2 3 1 3 2 6 1 1 2 2 2 1
Sample Output
YES 1 2
思路:
这题可能数据有点弱。
求每一个序列的和sum,然后求这个序列去除每一个a[i]其余的和,如果这个和是第一次出现,记录下来,若果这个和已经出现过一次,第二次出现(第一次和第二次不在同一个序列)记录下来,然后遍历和。
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<unordered_map>
#include<map>
using namespace std;
#define LL long long
const int N = 2e5+1000;
const long long mod = 1e9 + 7;
#define rep(i,a,b) for (int i = a; i <= b; i++)
#define per(i, a, b) for(int i=a;i>=b;i--)
unordered_map<LL, pair<int, int> > p;
int k,n;
int a[N];
int main()
{
cin >> k;
rep(j, 1, k)
{
cin >> n;
LL sum = 0;
rep(i, 1, n)
{
scanf("%d", &a[i]);
sum += a[i];
}
rep(i, 1, n)
{
if (!p[sum - a[i]].first) p[sum - a[i]].first = j;
else if (p[sum - a[i]].first!=j && !p[sum - a[i]].second)
p[sum - a[i]].second = j;
}
}
unordered_map<LL, pair<int, int> >::iterator it = p.begin();
LL x = 1e9, y = 1e9;
for (; it != p.end(); it++)
{
if (it->second.second&&it->second.first)
{
if (it->second.first + it->second.second<x + y || (it->second.first>x&& it->second.first + it->second.second ==x + y))
x = it->second.first, y = it->second.second;
}
}
if (x != 1e9 && y != 1e9)
{
printf("YES\n");
printf("%lld %lld\n", x, y);
}
else
printf("NO\n");
return 0;
}