using ll = long long;constexpr int MOD = 1e9+7;class Solution {public: int sumOfPower(vector<int>& nums, int k) { int n = nums.size(); vector<vector<int>> dp(n+1,vector<int>(k+1,0)); dp[0][0] = 1; // dp[i][j]: number of subsequences of length i and sum equal to j -> bottom-up solution for (int &d : nums) { for (int v = k; v >= d; v--) { for (int i = n; i > 0; i--) { dp[i][v] += dp[i-1][v-d]; // select d when length is i dp[i][v] %= MOD; } } } ll ans = 0, pow = 1; for (int i = n; i > 0; i--) { // when picking i elements, number of subsequences containing i elements (select from m=n-i left elements) is (mC0+mC1+...+mCm) = (1+1)^m = 3^m ans += pow*dp[i][k]; ans %= MOD; pow *= 2; pow %= MOD; } return ans; }};
using ll = long long;constexpr int MOD = 1e9+7;class Solution {public: int numSubseq(vector<int>& nums, int target) { sort(nums.begin(), nums.end()); int n = nums.size(); vector<int> p(n+1); // p[i]=2^i p[0] = 1; for (int i = 1; i <= n; i++) p[i] = (p[i-1]*2)%MOD; int target2 = target/2; ll ans = nums[0] <= target2; // length-1 subsequence for (int i = 1; i < n; i++) { ans += nums[i] <= target2; // length-1 subsequence int j = upper_bound(nums.begin(),nums.begin()+i,target-nums[i]) - nums.begin() - 1; // min element in [0..j], j<i -> subsequences are chosen from nums[j..i] if (j < 0) continue; ans += p[i] - p[i-j-1] + MOD; // sum of 2^(i-j-1)+...+2^(i-1), 2^(i-j-1) is number of subsequences are chosen from nums[j..i] with fixed j and i // 2^(i-j-1) + ... + 2^(i-1) = A // 2^(i-j) + ... + 2^i = 2A // -> A = 2^i - 2^(i-j-1) ans %= MOD; } return ans; }};
int dp[2001][4002];class Solution {public: // pick/notpick solution (slow but not TLE) int solve(vector<int> &values, int i = 0, int m = 0) { if (i == values.size()) return 0; if (dp[i][m] != -1) return dp[i][m]; int ans = solve(values, i+1, m); if (values[i] > m) ans = max(ans, solve(values, i+1, m+values[i]) + values[i]); return dp[i][m] = ans; } int maxTotalReward(vector<int>& values) { memset(dp, -1, sizeof(dp)); sort(values.begin(),values.end()); // remove duplicated values int n = 1; // new size of values for (int i = 1; i < values.size(); i++) if (values[i] != values[i-1]) swap(values[i], values[n++]); values.resize(n); return solve(values); } int maxTotalRewardBetter(vector<int>& values) { sort(values.begin(),values.end()); // remove duplicated values int n = 1; // new size of values for (int i = 1; i < values.size(); i++) if (values[i] != values[i-1]) swap(values[i], values[n++]); values.resize(n); int dp[4002] = {0}; // dp[v] is max total reward taken from values[i..] after receiving v reward int m = values[n-1]*2; for (int i = n-1; i >= 0; i--) { for (int v = 0; v < m; v++) { if (v < values[i]) dp[v] = max(dp[v], values[i] + dp[v+values[i]]); } } return dp[0]; }};
class Solution {public: vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) { vector<int> dist(n); // dist[i] is distance from 0 to i iota(dist.rbegin(),dist.rend(),0); vector<int> ans; vector<vector<int>> next(n,vector<int>()); for (auto &q : queries) { next[q[0]].push_back(q[1]); // dist from q[1] to n-1 is unchanged, all dist from [0..q[0]] to q[1] are changed because there is dist from i to i+1 for (int i = q[0]; i >= 0; i--) { dist[i] = min(dist[i], dist[i+1]+1); for (int &j : next[i]) dist[i] = min(dist[i], dist[j]+1); } ans.push_back(dist[0]); } return ans; }};
class Solution {public: // minimum steps to make s[i..j] int solve(string &s, vector<vector<int>> &dp, int i, int j) { if (i > j) return 0; if (dp[i][j] != -1) return dp[i][j]; if (s[i] == s[j]) return dp[i][j] = solve(s, dp, i, j-1); // make s[i..j] = a..a, and update s[i..j) int ans = solve(s, dp, i, j-1) + 1; // update s[i..j) and insert s[j] for (int k = i+1; k < j; k++) { if (s[k] == s[j]) { // solve(s, dp, i, k-1): solve s[i..k) // solve(s, dp, k, j-1): make s[k..j] = 'a..a', and update s[k..j) ans = min(ans, solve(s, dp, i, k-1) + solve(s, dp, k, j-1)); } } return dp[i][j] = ans; } int strangePrinter(string s) { // remove duplicate consecutive characters int n = 0; for (char &c : s) if (c != s[n]) s[++n] = c; s.resize(++n); vector<vector<int>> dp(n,vector<int>(n,-1)); for (int i = 0; i < n; i++) dp[i][i] = 1; return solve(s, dp, 0, n-1); }};
class Solution {public: int lis1(vector<int>& nums) { int n = nums.size(); if (n == 0) return 0; vector<int> q{nums[0]}; int j = 0; for (int i = 1; i < n; i++) { j = lower_bound(q.begin(), q.end(), nums[i]) - q.begin(); if (j < q.size()) { q[j] = nums[i]; } else { q.push_back(nums[i]); } } return j; // keep the last element } int lis2(vector<int>& nums) { int n = nums.size(); if (n == 0) return 0; vector<int> q{nums[0]}; for (int i = 1; i < n; i++) { int j = lower_bound(q.begin(), q.end(), nums[i]) - q.begin(); if (j < q.size()) { if (j > 0) q[j] = nums[i]; // keep the first element } else { q.push_back(nums[i]); } } return q.size(); } int maxPathLength(vector<vector<int>>& a, int k) { int n = a.size(); int x0 = a[k][0], y0 = a[k][1]; sort(a.begin(),a.end(),[](vector<int> &x, vector<int> &y) { return x[0] == y[0] ? x[1] > y[1] : x[0] < y[0]; }); // to avoid selecting 2 points with same x int l = lower_bound(a.begin(),a.end(),x0,[](const vector<int> &ai, int v) { return ai[0] < v; }) - a.begin(); int r = upper_bound(a.begin(),a.end(),x0,[](int v, const vector<int> &ai) { return v < ai[0]; }) - a.begin(); vector<int> q1; for (int i = 0; i < l; i++) q1.push_back(a[i][1]); q1.push_back(y0); vector<int> q2{y0}; for (int i = r; i < n; i++) q2.push_back(a[i][1]); return lis1(q1)+lis2(q2); }};
class Solution {public: int get_idx(char c) { switch (c) { case 'a': return 0; case 'e': return 1; case 'i': return 2; case 'o': return 3; case 'u': return 4; default: return -1; } } int findTheLongestSubstring(string s) { int n = s.length(); int q[32]; // 2^5 states memset(q, -1, sizeof(q)); q[0] = 0; // zero for all vowels int ans = 0; int m = 0; for (int i = 0; i < n; i++) { int t = get_idx(s[i]); if (t != -1) m ^= 1<<t; if (q[m] == -1) q[m] = i+1; ans = max(ans, i-q[m]+1); } return ans; }};
using ll = long long;constexpr int mod = 1e9+7;class Solution {public: int dp[1001][1024] = {}; // curr is state of current column j (from row 0 to row i-1), if i = 0, curr = 0 // prev is state of entire previous column j-1 int colorTheGrid(int m, int n, int i = 0, int j = 0, int curr = 0, int prev = 0) { if (i == m) return colorTheGrid(m, n, 0, j+1, 0, curr); // move to next column, curr becomes prev if (j == n) return 1; if (i == 0 && dp[j][prev]) return dp[j][prev]; // check for first row only // get color of left and up cells int left = (prev>>(i*2))&3, up = i == 0 ? 0 : (curr>>((i-1)*2))&3; ll ans = 0; for (int k = 1; k <= 3; k++) { if (k == left || k == up) continue; int mask = k<<(i*2); curr ^= mask; // set color of current cell ans += colorTheGrid(m, n, i+1, j, curr, prev); curr ^= mask; } if (i == 0) return dp[j][prev] = ans%mod; return ans%mod; }};
class Solution {public: int solve(vector<int> &values, vector<vector<int>> &dp, int i, int j) { if (dp[i][j] != -1) return dp[i][j]; int ans = 1e7, v = values[i]*values[j]; for (int k = i+1; k < j; k++) { ans = min(ans, solve(values, dp, i, k) + solve(values, dp, k, j) + v*values[k]); } return dp[i][j] = ans; } int minScoreTriangulation(vector<int>& values) { int n = values.size(); vector<vector<int>> dp(n,vector<int>(n,-1)); for (int i = 0; i < n-1; i++) dp[i][i+1] = 0; return solve(values, dp, 0, n-1); }};