Educational Codeforces Round 46 (Rated for Div. 2)
思路:有相同抵消,没有相同的对答案+1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 1e5 + 7; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; string a[101], b[101]; int n; map<string, int> mp; int main(){ scanf("%d", &n); for(int i = 1; i <= n; i++) cin >> a[i], mp[a[i]]++; int ans = 0; for(int i = 1; i <= n; i++) { cin >> b[i]; if(mp[b[i]]) { mp[b[i]]--; } else { ans++; } } printf("%d\n", ans); return 0; } /* */
思路:求一下前缀,如果要加一个开关肯定是加在原来是关的前面一个或者后面一个,枚举一下就好啦。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 420047; int n, M, sum[N], fsum[N], a[N]; int main(){ scanf("%d%d", &n, &M); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); a[++n] = M; for(int i = 1; i <= n; i++) { sum[i] = sum[i - 1]; if(i & 1) sum[i] += a[i] - a[i - 1]; fsum[i] = a[i] - sum[i]; } int ans = sum[n]; for(int i = 1; i < n; i++) { if(i & 1) { if(a[i] > a[i - 1] + 1) { int ret = a[i] - a[i - 1] - 1; ret += fsum[n] - fsum[i]; ret += sum[i - 1]; ans = max(ans, ret); } if(a[i] < a[i + 1] - 1) { int ret = sum[i]; ret += fsum[n] - fsum[i + 1]; ret += a[i + 1] - a[i] - 1; ans = max(ans, ret); } } } printf("%d\n", ans); return 0; } /* */
思路:离散化差分标记搞一搞
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 1e6 + 7 + 2e5; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; LL n, tot, in[N], out[N], ans[N]; LL hs[N], l[N], r[N]; int main(){ scanf("%lld", &n); for(int i = 1; i <= n; i++) { scanf("%lld%lld", &l[i], &r[i]); hs[++tot] = l[i]; hs[++tot] = r[i]; hs[++tot] = l[i] + 1; hs[++tot] = l[i] - 1; hs[++tot] = r[i] + 1; hs[++tot] = r[i] - 1; } sort(hs + 1, hs + 1 + tot); tot = unique(hs + 1, hs + 1 + tot) - hs - 1; for(int i = 1; i <= n; i++) { int pos1 = lower_bound(hs + 1, hs + 1 + tot, l[i]) - hs; int pos2 = lower_bound(hs + 1, hs + 1 + tot, r[i]) - hs; in[pos1]++; out[pos2]++; } LL cnt = 0; for(int i = 1; i < tot; i++) { cnt += in[i]; ans[cnt]++; cnt -= out[i]; LL num = hs[i + 1] - hs[i] - 1; ans[cnt] += num; } cnt += in[tot]; ans[cnt]++; for(int i = 1; i <= n; i++) printf("%lld ", ans[i]); return 0; } /* */
D - Yet Another Problem On a Subsequence
题目大意:给你n个数字 (n <= 1000), 问你有多少个子序列是good sequence
good sequence的定义是能变成若干个good arrays
good array 的定义是这个数组的第一个元素的值等于这个数组的length - 1。
思路: A了三题之后日常开始挂机。。。 还是太菜啦!!!!
比赛的时候感觉是个dp,但是不知到如何定义状态。。。
后来发现原来我看错了题,原来是把good sequence划分成若干个good arrays
我们定义dp[ i ],表示从第 i 个开始,并且 i 作为一个array第一个元素的的合法答案的方案数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 1e3 + 7; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; int a[N], dp[N], C[N][N], n; void init() { for(int i = (C[0][0] = 1); i < N; i++) for(int j = (C[i][0] = 1); j < N; j++) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod; } int main() { init(); scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } dp[n + 1] = 1; for(int i = n; i >= 1; i--) { if(a[i] > 0) { for(int j = i + a[i] + 1; j <= n + 1; j++) { dp[i] = (dp[i] + 1LL * dp[j] * C[j - i - 1][a[i]]) % mod; } } } int ans = 0; for(int i = 1; i <= n; i++) { ans = (ans + dp[i]) % mod; } printf("%d\n", ans); return 0; } /* */