#include <iostream>
#include <vector>
#include <unordered_map>
#include <queue>
using namespace std;
int subarraySum(const vector<int>& nums,int target)
{
unordered_map<int,int>map;
int sum = 0, res = 0;
map[0] = 1;
for(int num:nums)
{
sum += num;
if(map.count(sum - target))res+=map[sum - target];
++map[sum];
}
return res;
}
int subarrayDivByK(const vector<int>& nums,int k)
{
unordered_map<int,int>map;
map[0] = 1;
int prefix = 0,res = 0;
for(int num:nums)
{
prefix = (prefix + num % k + k) % k;
res += map[prefix];
++map[prefix];
}
return res;
}
bool checkSubArraySum(const vector<int>& nums, int k)
{
int sum = 0;
unordered_map<int,int>map;
map[0] = -1;
for(int i = 0; i < nums.size(); ++i)
{
sum += nums[i];
if(k != 0)sum %= k;
if(map.count(sum))
{
if(i - map[sum] > 1)return true;
}
else
{
map[sum] = i;
}
}
return false;
}
int findMaxLen(vector<int>& nums)
{
for(int i = 0; i < nums.size(); ++i)
{
if(nums[i] == 0)nums[i] = -1;
}
int res = 0,sum = 0;
unordered_map<int,int>map;
map[0] = -1;
for(int i = 0; i < nums.size(); ++i)
{
sum += nums[i];
if(map.count(sum)) res = max(res,i-map[sum]);
}
return res;
}
vector<int>getModifiedArray(int length, const vector<vector<int>>& updates)
{
vector<int>res(length,0);
for(auto update:updates)
{
int val = update[2];
int start = update[0];
int end = update[1];
res[start]+=val;
if(end < length - 1)res[end + 1]-=val;
}
int sum = 0;
for(int i = 0; i < length; ++i)
{
sum += res[i];
res[i] = sum;
}
return res;
}
void print(const vector<int>& nums)
{
for(int num : nums)
{
cout << num << " ";
}
cout << endl;
}
int minSubArrayLen(const vector<int>& nums,int target)
{
int left = 0, n = nums.size(), res = INT_MAX, sum = 0;
for(int i = 0; i < n; ++i)
{
sum += nums[i];
while(sum >= target)
{
res = min(res,i - left + 1);
sum -= nums[left++];
}
}
return res == INT_MAX ? 0 : res;
}
int shortestSubarray(const vector<int>&A,int k)
{
int n = A.size(), res = n + 1;
vector<int>sum(n+1);
for(int i = 0; i < n; ++i)
{
sum[i+1] = sum[i] + A[i];
}
deque<int>q;
for(int i = 0; i < n + 1; ++i)
{
while(!q.empty() && sum[q.front()] >= sum[i])q.pop_back();
while(!q.empty() && sum[i] - sum[q.front()] >= k)
{
res = min(res,i - q.front());
q.pop_front();
}
q.push_back(i);
}
return res <= n ? res : -1;
}
int main()
{
//LeetCode560
vector<int>nums{1,2,3};
int k = 3;
cout << subarraySum(nums,k) << endl;
//LeetCode974
nums={4,5,0,-2,-3,1};
k = 5;
cout << subarrayDivByK(nums,k) << endl;
//LeetCode523
nums = {23,2,4,6,7};
k = 6;
cout << checkSubArraySum(nums,k) << endl;
//LeetCode525
nums = {0,1,0};
cout << findMaxLen(nums) << endl;
//LeetCode370
int len = 5;
vector<vector<int>>updates{{1,3,2},{2,4,3},{0,2,-2}};
print(getModifiedArray(len,updates));
//LeetCode209
int target = 7;
nums = {2,3,1,2,4,3};
cout << minSubArrayLen(nums,target) << endl;
//LeetCode862
nums = {2,-1,2};
k = 3;
cout << shortestSubarray(nums,k) << endl;
return 0;
}