Count Unordered Zero-Sum Teams
Autumn Tournament (2011)
Submission name: zerosum.cpp
Problem summary
Count unordered triples of different participant indices whose three integer values sum to zero. Participants remain distinct when their values are equal.
Input
N, followed by N integer values.
Output
The number of zero-sum triples.
Constraints
1 ≤ N ≤ 10000; −10000 ≤ each value ≤ 10000.
Worked example
Original statement sample.
Input
10 2 -5 2 3 -4 7 -4 0 1 -6
Output
6
Solution analysis
- Sort the values. Fix the smallest index i of a triple, then search for two later values with sum −a[i]. Start one pointer at i+1 and the other at N−1. A too-small sum requires increasing the left value; a too-large sum requires decreasing the right value.
- When the sum is zero and the endpoint values differ, count their equal-value runs. Every left-run participant can pair with every right-run participant, contributing leftCount·rightCount. Skip both complete runs afterwards. If the endpoint values are equal, all remaining positions have that value: add c(c−1)/2 and finish this i.
- The sample has two different participants of value 2 and two of value −4. Thus the value pattern (2,2,−4) gives two teams, while (3,−4,1) also gives two. Together with the two choices of participant 2 in (−5,2,3), the answer is 6.
- Do not skip duplicate fixed values: each fixed index represents a different participant. Use long long for the answer, since even the all-zero case has C(N,3) teams.
Why it works
For a fixed i, sorted order makes each pointer move discard only pairs that cannot meet the target. At a successful sum, run multiplication counts every index pair with those endpoint values exactly once. Every triple has one unique smallest sorted index i, so summing these counts gives precisely all unordered teams.
Watch out. Do not count only distinct value triples. Do not skip repeated fixed indices. Handle equal left/right values with a binomial count rather than run multiplication, and count only indices i<left<right.
Commented C++17 solution
An independently written complete program with standard headers.
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n;
cin>>n;
vector<int>values(n);
for(int&value:values){
cin>>value;
}
sort(values.begin(),values.end());
long long answer=0;
for(int i=0;i<n;i++){
int left=i+1;
int right=n-1;
while(left<right){
int sum=values[i]+values[left]+values[right];
if(sum<0){
left++;
}
else if(sum>0){
right--;
}
else if(values[left]==values[right]){
long long count=right-left+1;
answer+=count*(count-1)/2;
break;
}
else{
int leftValue=values[left];
int rightValue=values[right];
long long leftCount=0;
long long rightCount=0;
while(left<=right&&values[left]==leftValue){
left++;
leftCount++;
}
while(right>=left&&values[right]==rightValue){
right--;
rightCount++;
}
// Equal values belong to distinct participants.
answer+=leftCount*rightCount;
}
}
}
cout<<answer<<'\n';
}