- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 107 lines of C++ from the credited upstream file 3017.cpp.
- The implementation visibly relies on sequence storage.
- 5 loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public:3 4 vector<long long> countOfPairs(int n, int x, int y) {5 if (x > y)6 swap(x, y);7 8 const int ringLen = y - x + 1;9 const int leftLineLen = x - 1;10 const int rightLineLen = n - y;11 12 vector<long long> ans(n);13 ans = addVectors(ans, bothInRing(n, ringLen));14 ans = addVectors(ans, bothInTheSameLine(n, leftLineLen));15 ans = addVectors(ans, bothInTheSameLine(n, rightLineLen));16 ans = addVectors(ans, lineToRing(n, leftLineLen, ringLen));17 ans = addVectors(ans, lineToRing(n, rightLineLen, ringLen));18 ans = addVectors(ans, lineToLine(n, x, y, leftLineLen, rightLineLen));19 for (long long& freq : ans)20 freq *= 2;21 return ans;22 }23 24 private:25 26 27 vector<long long> bothInRing(int n, int ringLen) {28 vector<long long> res(n);29 for (int k = 1; k <= (ringLen - 1) / 2; ++k)30 res[k - 1] += ringLen;31 if (ringLen % 2 == 0)32 res[ringLen / 2 - 1] += ringLen / 2;33 return res;34 }35 36 37 38 vector<long long> bothInTheSameLine(int n, int lineLen) {39 vector<long long> res(n);40 for (int k = 1; k <= lineLen; ++k)41 res[k - 1] += lineLen - k;42 return res;43 }44 45 46 47 48 vector<long long> lineToRing(int n, int lineLen, int ringLen) {49 vector<long long> res(n);50 for (int k = 1; k <= lineLen + ringLen; ++k) {51 52 53 54 55 56 const int maxInRingLen = min(k - 1, ringLen / 2);57 58 const int minInRingLen = max(0, k - lineLen);59 if (minInRingLen <= maxInRingLen) {60 61 62 63 64 65 66 res[k - 1] += (maxInRingLen - minInRingLen + 1) * 2;67 if (minInRingLen == 0)68 69 res[k - 1] -= 1;70 if (maxInRingLen * 2 == ringLen)71 72 73 74 res[k - 1] -= 1;75 }76 }77 return res;78 }79 80 81 82 vector<long long> lineToLine(int n, int x, int y, int leftLineLen,83 int rightLineLen) {84 vector<long long> res(n);85 for (int k = 1; k <= leftLineLen + rightLineLen + 2; ++k) {86 87 88 89 90 91 const int maxInLeft = min(leftLineLen, k - 1 - (x < y));92 93 const int minInLeft = max(1, k - rightLineLen - (x < y));94 if (minInLeft <= maxInLeft)95 res[k - 1] += maxInLeft - minInLeft + 1;96 }97 return res;98 }99 100 vector<long long> addVectors(const vector<long long>& a,101 const vector<long long>& b) {102 vector<long long> res(a.size());103 transform(a.begin(), a.end(), b.begin(), res.begin(), plus<int>());104 return res;105 };106};107