- 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
- 105 lines of C++ from the credited upstream file 3015.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 vector<int> countOfPairs(int n, int x, int y) {4 if (x > y)5 swap(x, y);6 7 const int ringLen = y - x + 1;8 const int leftLineLen = x - 1;9 const int rightLineLen = n - y;10 11 vector<int> ans(n);12 ans = addVectors(ans, bothInRing(n, ringLen));13 ans = addVectors(ans, bothInTheSameLine(n, leftLineLen));14 ans = addVectors(ans, bothInTheSameLine(n, rightLineLen));15 ans = addVectors(ans, lineToRing(n, leftLineLen, ringLen));16 ans = addVectors(ans, lineToRing(n, rightLineLen, ringLen));17 ans = addVectors(ans, lineToLine(n, x, y, leftLineLen, rightLineLen));18 for (int& freq : ans)19 freq *= 2;20 return ans;21 }22 23 private:24 25 26 vector<int> bothInRing(int n, int ringLen) {27 vector<int> res(n);28 for (int k = 1; k <= (ringLen - 1) / 2; ++k)29 res[k - 1] += ringLen;30 if (ringLen % 2 == 0)31 res[ringLen / 2 - 1] += ringLen / 2;32 return res;33 }34 35 36 37 vector<int> bothInTheSameLine(int n, int lineLen) {38 vector<int> res(n);39 for (int k = 1; k <= lineLen; ++k)40 res[k - 1] += lineLen - k;41 return res;42 }43 44 45 46 47 vector<int> lineToRing(int n, int lineLen, int ringLen) {48 vector<int> res(n);49 for (int k = 1; k <= lineLen + ringLen; ++k) {50 51 52 53 54 55 const int maxInRingLen = min(k - 1, ringLen / 2);56 57 const int minInRingLen = max(0, k - lineLen);58 if (minInRingLen <= maxInRingLen) {59 60 61 62 63 64 65 res[k - 1] += (maxInRingLen - minInRingLen + 1) * 2;66 if (minInRingLen == 0)67 68 res[k - 1] -= 1;69 if (maxInRingLen * 2 == ringLen)70 71 72 73 res[k - 1] -= 1;74 }75 }76 return res;77 }78 79 80 81 vector<int> lineToLine(int n, int x, int y, int leftLineLen,82 int rightLineLen) {83 vector<int> res(n);84 for (int k = 1; k <= leftLineLen + rightLineLen + 2; ++k) {85 86 87 88 89 90 const int maxInLeft = min(leftLineLen, k - 1 - (x < y));91 92 const int minInLeft = max(1, k - rightLineLen - (x < y));93 if (minInLeft <= maxInLeft)94 res[k - 1] += maxInLeft - minInLeft + 1;95 }96 return res;97 }98 99 vector<int> addVectors(const vector<int>& a, const vector<int>& b) {100 vector<int> res(a.size());101 transform(a.begin(), a.end(), b.begin(), res.begin(), plus<int>());102 return res;103 };104};105