#include <iostream> #include <vector> #include <set> #include <map> #include <algorithm> #include <iomanip> //#define __DEBUG #define KEY first #define VALUE second #define REP(x,n) for (int x=0;x<(n);++x) #define VAR(x,n) __typeof(n) x = (n) #define FOREACH(x,c) for(VAR(x, (c).begin()); x != (c).end(); ++x) #define CONTAINS(x,elem) ((x).find(elem) != (x).end()) #ifdef __DEBUG #define DEBUG(x) x #else #define DEBUG(x) #endif using namespace std; void solve(); int main() { ios_base::sync_with_stdio(0); cin.tie(0); solve(); return 0; } #define MAX_N 501 int input[MAX_N]; int sumPrefix[MAX_N]; // sumPrefix[x+1] = sum(input[0..x] inclusive) map<int,int> numbersCount; long long findResultWithSingle(const map<int,int>::iterator firstNumber) { if (numbersCount.size() < 3) { return false; } long long result = 0; auto secondNumber = next(firstNumber); auto thirdNumber = prev(numbersCount.end()); long long firstValue = firstNumber->VALUE; while (secondNumber != thirdNumber) { int diff = firstNumber->KEY + secondNumber->KEY + thirdNumber->KEY; DEBUG( if (diff != 0) { //DEBUG(cerr << "triple " << firstNumber->KEY << "+" << secondNumber->KEY << "+" << thirdNumber->KEY << " does not match by " << diff << endl;) } ) if (diff > 0) { --thirdNumber; } else { if (diff == 0) { DEBUG(cerr << "adding single result - " << firstNumber->KEY << "+" << secondNumber->KEY << "+" << thirdNumber->KEY << " - " << (firstValue * secondNumber->VALUE * thirdNumber->VALUE) << " combinations" << endl;) result += firstValue * secondNumber->VALUE * thirdNumber->VALUE; } ++secondNumber; } } // if (secondNumber->VALUE > 1 && (secondNumber->KEY * 2 + firstNumber->KEY) == 0) { // DEBUG(cerr << "adding reversed double result - " << firstNumber->KEY << "+" << secondNumber->KEY << "+" << secondNumber->KEY << " - " << (firstValue * secondNumber->VALUE * (secondNumber->VALUE-1) / 2) << " combinations" << endl;) // result += firstValue * secondNumber->VALUE * (secondNumber->VALUE-1) / 2; // } return result; } long long findResultWithDouble(const map<int,int>::iterator firstNumber) { if (firstNumber->VALUE < 2 || firstNumber->KEY == 0) { return 0; } auto secondElement = numbersCount.find(0 - (2*firstNumber->KEY)); if (secondElement == numbersCount.end()) { return 0; } else { long long value = firstNumber->VALUE; DEBUG(cerr << "adding double result - " << firstNumber->KEY << "+" << firstNumber->KEY << "+" << secondElement->KEY << " - " << (value * (value-1) / 2 * secondElement->VALUE) << " combinations" << endl;) return value * (value-1) / 2 * secondElement->VALUE; } } long long findResultWithTriple(const map<int,int>::iterator firstNumber) { if (firstNumber->KEY != 0 || firstNumber->VALUE < 3) { return 0; } else { long long value = firstNumber->VALUE; DEBUG(cerr << "adding triple result - " << firstNumber->KEY << "+" << firstNumber->KEY << "+" << firstNumber->KEY << " - " << (value * (value-1) * (value-2) / 6) << " combinations" << endl;) return value * (value-1) * (value-2) / 6; } } void solve() { int n; cin>>n; REP(x,n) { cin>>input[x]; sumPrefix[x+1] = sumPrefix[x] + input[x]; } REP(end,n+1) REP(beg,end) ++numbersCount[sumPrefix[end]-sumPrefix[beg]]; DEBUG( cerr << "count: "<<endl; FOREACH(it, numbersCount) cerr << it->first << ": "<<it->second << endl; ) long long result = 0LL; FOREACH(first, numbersCount) { result += findResultWithSingle(first); result += findResultWithDouble(first); result += findResultWithTriple(first); } cout << result << endl; //input = 7 -4 2 //sumPrefix = 0 7 3 5 //input = -3 0 4 -2 3 //sumPrefix = 0 -3 -3 1 -1 2 // all elements = [-3 -3 1 -1 2] [0 4 2 5] [4 2 5] [-2 1] [3] // -3 -3 -2 -1 0 1 1 2 2 2 3 4 4 5 5 // result = 29: /* [-3 -2 5] x4 /2*2 [-3 -1 4] x4 /2*2 [-3 0 3] x2 [-3 1 2] x12 /2*2*3 [-2 -1 3] x1 [-2 0 2] x3 [-2 1 1] x1 [-1 0 1] x2 */ }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | #include <iostream> #include <vector> #include <set> #include <map> #include <algorithm> #include <iomanip> //#define __DEBUG #define KEY first #define VALUE second #define REP(x,n) for (int x=0;x<(n);++x) #define VAR(x,n) __typeof(n) x = (n) #define FOREACH(x,c) for(VAR(x, (c).begin()); x != (c).end(); ++x) #define CONTAINS(x,elem) ((x).find(elem) != (x).end()) #ifdef __DEBUG #define DEBUG(x) x #else #define DEBUG(x) #endif using namespace std; void solve(); int main() { ios_base::sync_with_stdio(0); cin.tie(0); solve(); return 0; } #define MAX_N 501 int input[MAX_N]; int sumPrefix[MAX_N]; // sumPrefix[x+1] = sum(input[0..x] inclusive) map<int,int> numbersCount; long long findResultWithSingle(const map<int,int>::iterator firstNumber) { if (numbersCount.size() < 3) { return false; } long long result = 0; auto secondNumber = next(firstNumber); auto thirdNumber = prev(numbersCount.end()); long long firstValue = firstNumber->VALUE; while (secondNumber != thirdNumber) { int diff = firstNumber->KEY + secondNumber->KEY + thirdNumber->KEY; DEBUG( if (diff != 0) { //DEBUG(cerr << "triple " << firstNumber->KEY << "+" << secondNumber->KEY << "+" << thirdNumber->KEY << " does not match by " << diff << endl;) } ) if (diff > 0) { --thirdNumber; } else { if (diff == 0) { DEBUG(cerr << "adding single result - " << firstNumber->KEY << "+" << secondNumber->KEY << "+" << thirdNumber->KEY << " - " << (firstValue * secondNumber->VALUE * thirdNumber->VALUE) << " combinations" << endl;) result += firstValue * secondNumber->VALUE * thirdNumber->VALUE; } ++secondNumber; } } // if (secondNumber->VALUE > 1 && (secondNumber->KEY * 2 + firstNumber->KEY) == 0) { // DEBUG(cerr << "adding reversed double result - " << firstNumber->KEY << "+" << secondNumber->KEY << "+" << secondNumber->KEY << " - " << (firstValue * secondNumber->VALUE * (secondNumber->VALUE-1) / 2) << " combinations" << endl;) // result += firstValue * secondNumber->VALUE * (secondNumber->VALUE-1) / 2; // } return result; } long long findResultWithDouble(const map<int,int>::iterator firstNumber) { if (firstNumber->VALUE < 2 || firstNumber->KEY == 0) { return 0; } auto secondElement = numbersCount.find(0 - (2*firstNumber->KEY)); if (secondElement == numbersCount.end()) { return 0; } else { long long value = firstNumber->VALUE; DEBUG(cerr << "adding double result - " << firstNumber->KEY << "+" << firstNumber->KEY << "+" << secondElement->KEY << " - " << (value * (value-1) / 2 * secondElement->VALUE) << " combinations" << endl;) return value * (value-1) / 2 * secondElement->VALUE; } } long long findResultWithTriple(const map<int,int>::iterator firstNumber) { if (firstNumber->KEY != 0 || firstNumber->VALUE < 3) { return 0; } else { long long value = firstNumber->VALUE; DEBUG(cerr << "adding triple result - " << firstNumber->KEY << "+" << firstNumber->KEY << "+" << firstNumber->KEY << " - " << (value * (value-1) * (value-2) / 6) << " combinations" << endl;) return value * (value-1) * (value-2) / 6; } } void solve() { int n; cin>>n; REP(x,n) { cin>>input[x]; sumPrefix[x+1] = sumPrefix[x] + input[x]; } REP(end,n+1) REP(beg,end) ++numbersCount[sumPrefix[end]-sumPrefix[beg]]; DEBUG( cerr << "count: "<<endl; FOREACH(it, numbersCount) cerr << it->first << ": "<<it->second << endl; ) long long result = 0LL; FOREACH(first, numbersCount) { result += findResultWithSingle(first); result += findResultWithDouble(first); result += findResultWithTriple(first); } cout << result << endl; //input = 7 -4 2 //sumPrefix = 0 7 3 5 //input = -3 0 4 -2 3 //sumPrefix = 0 -3 -3 1 -1 2 // all elements = [-3 -3 1 -1 2] [0 4 2 5] [4 2 5] [-2 1] [3] // -3 -3 -2 -1 0 1 1 2 2 2 3 4 4 5 5 // result = 29: /* [-3 -2 5] x4 /2*2 [-3 -1 4] x4 /2*2 [-3 0 3] x2 [-3 1 2] x12 /2*2*3 [-2 -1 3] x1 [-2 0 2] x3 [-2 1 1] x1 [-1 0 1] x2 */ } |