P1748 a+b+c+d==0
求和问题可以被看做是以下的公式,给定 A,B,C,D 四个列表,计算有多少四元组满足 (a, b, c, d) ∈ A × B × C × D 且 a + b + c + d = 0。我们推测所有的列表都有 n 个数字。
问题描述:
注:不同的四元组是指元素位置不一样的四元组
数据范围 n<=2e3
样例输入
输入的第一个数字指明有 T 组。每一组这样描述,第一行是列表大小 n, 然后有 n 行。每一行都有四个整型数字,分别属于 A,B,C,D 四列。
1
6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45
样例输出
5
对于每一个测试用例,统计有多少个四元组满足他们的和是 0 。每一组数据一行。
遇到的问题,超时。
我的思路:将a和b,c和d分别分为一组,计算出ai+bj和ci+dj所有可能的值,并用sum1和sum2进行保存。复杂度为n^2;sort 排序sum2数组复杂度为n^2logn^2;接下来用upp_bound和lower_bound函数找到-sum1[i]在sum2中个数,复杂度为n^2*logn^2。但是最后还是超时了。
我得尝试代码:
#include<iostream>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>v1;
vector<int>v2;
vector<int>v3;
vector<int>v4;
vector<int>sum1;
vector<int>sum2;
int main()
{
int t=0;
cin>>t;
while(t--) //输入复杂度n
{
int n=0;
cin>>n;
int a=0,b=0,c=0,d=0;
for(int i=0;i<n;++i)
{
cin>>a>>b>>c>>d;
v1.push_back(a);
v2.push_back(b);
v3.push_back(c);
v4.push_back(d);
}
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
{
sum1.push_back(v1[i]+v2[j]);
}
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
{
sum2.push_back(v3[i]+v4[j]);
}
sort(sum2.begin(),sum2.end());
int ans=0;
vector<int>::iterator s1;
vector<int>::iterator s2;
for(int i=0;i<sum1.size();++i)
{
s1=lower_bound(sum2.begin(),sum2.end(),-sum1[i]);
s2=upper_bound(sum2.begin(),sum2.end(),-sum1[i]);
ans+=s2-s1;
}
cout<<ans<<endl;
}
return 0;
}
问题:
根据问题规模2e3;时间复杂度应该不超过n^3;
我的代码根据我上文的尝试分析,实在n^2logn^2级别的,是不应该超时的呀。请大家帮我看看,是否是我的复杂度分析有问题。或者是否有更好的解决方法。orz