codeforces round #426 div 2
A: 如果n%2=0或2就是undefined,否则判一下转一下是否能到达状态
#include<bits/stdc++.h> using namespace std; int n; char s[10], t[10]; int main() { scanf("%s%s%d", s, t, &n); if(n % 4 == 0 || n % 4 == 2) { puts("undefined"); return 0; } if((s[0] == '^' && t[0] == '>') || (s[0] == '>' && t[0] == 'v') || (s[0] == 'v' && t[0] == '<') || (s[0] == '<' && t[0] == '^')) { if(n % 4 == 1) { puts("cw"); return 0; } if(n % 4 == 3) { puts("ccw"); return 0; } } else { if(n % 4 == 1) { puts("ccw"); return 0; } else { puts("cw"); return 0; } } return 0; }
B:cf常见套路,开个桶,扫一遍,看有没有超过
#include<bits/stdc++.h> using namespace std; int n, k, tot; char s[1000010]; int t[27], tt[27]; int main() { scanf("%d%d%s", &n, &k, s); int len = strlen(s); for(int i = 0; i < len; ++i) { ++t[s[i] - 'A']; ++tt[s[i] - 'A']; } for(int i = 0; i < len; ++i) { if(t[s[i] - 'A'] == tt[s[i] - 'A']) ++tot; if(tot > k) { puts("YES"); return 0; } --t[s[i] - 'A']; if(t[s[i] - 'A'] == 0) --tot; } puts("NO"); return 0; }
C:思维僵化,写了个线性筛。其实我们可以二分,因为a*b肯定是立方数,然后求出gcd,因为gcd至少是x,所以判一下x*x*x==a*b和gcd%x==0就行了,gcd必须包含x,因为我们可以让一个数一直乘k,另一个*k^2,这样gcd=x,否则gcd会比x大,且能整除x
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n; int main() { scanf("%d", &n); while(n--) { ll a, b, x = 0, l = 0, r = 1000010; scanf("%lld%lld", &a, &b); while(r - l > 1) { ll mid = (l + r) >> 1; if(mid * mid * mid <= a * b) l = x = mid; else r = mid; } ll t = __gcd(a, b); if(x * x * x == a * b && t % x == 0) puts("Yes"); else puts("No"); } return 0; }
D:首先可以知道是dp,dp[i][k]表示选到第i个数,分了k段,dp[i][k]=dp[j][k-1]+calc(j+1,i),calc是计算颜色数,那么这里我们用线段树优化一下,算出每个颜色上一次出现的位置,每扫到一个位置,把从这里到上一个位置的dp值+1,也就是说这一段出现了一种新颜色,还有一种做法是整体二分,因为这个式子有决策单调性,那么整体二分直接搞就行了,如果后面的dp值+calc大于之前所有dp+calc,那么之后肯定也会更优,因为再加入颜色,后面的颜色数比之前的少,加入新颜色也肯定比之前优
线段树
#include<bits/stdc++.h> using namespace std; const int N = 35010; int n, K; int r[N], last[N], dp[N][55], bin[N]; struct seg { int tree[N << 2], tag[N << 2]; void clr() { tag[1] = -1; tree[1] = 0; } void pushdown(int x) { if(tag[x] == 0) return; if(tag[x] == -1) { tag[x << 1] = tag[x << 1 | 1] = tag[x]; tree[x << 1] = tree[x << 1 | 1] = 0; tag[x] = 0; return; } tag[x << 1] += tag[x]; tag[x << 1 | 1] += tag[x]; tree[x << 1] += tag[x]; tree[x << 1 | 1] += tag[x]; tag[x] = 0; } void update(int l, int r, int x, int a, int b, int delta) { if(l > b || r < a) return; if(l >= a && r <= b) { tag[x] += delta; tree[x] += delta; return; } pushdown(x); int mid = (l + r) >> 1; update(l, mid, x << 1, a, b, delta); update(mid + 1, r, x << 1 | 1, a, b, delta); tree[x] = max(tree[x << 1], tree[x << 1 | 1]); } int query(int l, int r, int x, int a, int b) { if(l > b || r < a) return 0; if(l >= a && r <= b) return tree[x]; pushdown(x); int mid = (l + r) >> 1; return max(query(l, mid, x << 1, a, b), query(mid + 1, r, x << 1 | 1, a, b)); } } t; int main() { scanf("%d%d", &n, &K); for(int i = 1; i <= n; ++i) { int c; scanf("%d", &c); r[i] = last[c]; last[c] = i; if(bin[c] == 0) dp[i][1] = dp[i - 1][1] + 1; else dp[i][1] = dp[i - 1][1]; ++bin[c]; } if(K == 1) { printf("%d\n", dp[n][1]); return 0; } for(int k = 2; k <= K; ++k) { t.clr(); for(int i = k - 1; i <= n; ++i) { t.update(1, n, 1, max(r[i], k - 1), i - 1, 1); dp[i][k] = t.query(1, n, 1, k - 1, i - 1); t.update(1, n, 1, i, i, dp[i][k - 1]); } } printf("%d\n", dp[n][K]); return 0; }
tle的整体二分 开了一堆map,t了
#include<bits/stdc++.h> using namespace std; const int N = 35010; int n, k; int dp[N][60], a[N]; map<int, int> bin; map<int, int> distinct[N]; int build(int l, int r) { bin.clear(); distinct[r].clear(); for(int i = r; i >= l; --i) if(bin.find(a[i]) == bin.end()) { distinct[r][i] = distinct[r][i + 1] + 1; bin[a[i]] = 1; } else distinct[r][i] = distinct[r][i + 1]; } void divide(int l, int r, int opt_l, int opt_r, int k) { if(l > r) return; int mid = (l + r) >> 1, opt_m = opt_l; build(opt_l, mid); for(int i = opt_l; i <= min(opt_r, mid); ++i) { int delta = dp[i - 1][k - 1] + distinct[mid][i]; if(delta > dp[mid][k]) { dp[mid][k] = delta; opt_m = i; } } distinct[mid].clear(); divide(l, mid - 1, opt_l, opt_m, k); divide(mid + 1, r, opt_m, opt_r, k); } int main() { scanf("%d%d", &n, &k); for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); if(bin[a[i]] == 0) dp[i][1] = dp[i - 1][1] + 1; else dp[i][1] = dp[i - 1][1]; ++bin[a[i]]; } for(int i = 2; i <= k; ++i) divide(k, n, 1, n, i); printf("%d\n", dp[n][k]); return 0; }