HDU多校Round 5
Solved:3
rank:71
E. Everything Has Changed
#include <bits/stdc++.h> using namespace std; const double PI = acos(-1.0); int main() { int T; scanf("%d", &T); while(T--) { int m; double R; scanf("%d%lf", &m, &R); double ans = 2.0 * PI * R; for(int i = 1; i <= m; i++) { double x, y, r; scanf("%lf%lf%lf", &x, &y, &r); double dis = sqrt(x * x + y * y); if(dis + r < R || dis - r >= R) continue; double c1 = acos((r * r + dis * dis - R * R) / (2.0 * dis * r)); ans += c1 * 2.0 * r; double c2 = acos((R * R + dis * dis - r * r) / (2.0 * dis * R)); ans -= c2 * 2.0 * R; } printf("%.20lf\n", ans); } return 0; }
G. Glad You Came
#include <bits/stdc++.h> using namespace std; typedef unsigned int ui; typedef long long ll; ui x, y, z; ui sui() { x ^= x << 11; x ^= x >> 4; x ^= x << 5; x ^= x >> 14; ui p = x ^ (y ^ z); x = y; y = z; z = p; return z; } ll zx[400005]; int lz[400005]; void pushup(int rt) { zx[rt] = min(zx[rt << 1], zx[rt << 1 | 1]); } void pushdown(int rt) { if(lz[rt]) { lz[rt << 1] = max(lz[rt << 1], lz[rt]); lz[rt << 1 | 1] = max(lz[rt << 1 | 1], lz[rt]); zx[rt << 1] = max(zx[rt << 1], (ll)lz[rt << 1]); zx[rt << 1 | 1] = max(zx[rt << 1 | 1], (ll)lz[rt << 1 | 1]); lz[rt] = 0; } } void build(int l, int r, int rt) { if(l == r) { zx[rt] = lz[rt] = 0; return; } zx[rt] = lz[rt] = 0; int m = l + r >> 1; build(l, m, rt << 1); build(m + 1, r, rt << 1 | 1); } void update(int ql, int qr, int v, int l, int r, int rt) { if(zx[rt] >= v) return; if(ql <= l && qr >= r) { lz[rt] = max(lz[rt], v); zx[rt] = max(zx[rt], (ll)v); return; } pushdown(rt); int m = l + r >> 1; if(ql <= m) update(ql, qr, v, l, m, rt << 1); if(qr > m) update(ql, qr, v, m + 1, r, rt << 1 | 1); pushup(rt); } ll query(int l, int r, int rt) { if(l == r) return 1LL * (ll)l * zx[rt]; pushdown(rt); ll res = 0; int m = l + r >> 1; res ^= query(l, m, rt << 1); res ^= query(m + 1, r, rt << 1 | 1); return res; } int main() { int T; scanf("%d", &T); while(T--) { int n, m; cin>>n>>m>>x>>y>>z; int l, r, v; build(1, n, 1); for(int i = 1; i <= m; i++) { ui f1 = sui(), f2 = sui(), f3 = sui(); l = min(f1 % n + 1, f2 % n + 1); r = max(f1 % n + 1, f2 % n + 1); v = f3 % (1 << 30); update(l, r, v, 1, n, 1); } printf("%lld\n", query(1, n, 1)); } return 0; }
H. Hills And Valleys
构造一个0-9的数组 每次枚举翻转哪两个数就一共45次
然后把两个数组跑一个lcs 枚举翻转的那个数组可以多次匹配
#include <bits/stdc++.h> using namespace std; char s[100005]; int a[100005]; int b[15]; int dp[100005][15]; int l[100005][15]; int r[100005][15]; int n, cnt, nl, nr; int ans, ansl, ansr; void solve(int len) { for(int i = 1; i <= len; i++) dp[0][i] = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= len; j++) { dp[i][j] = dp[i - 1][j]; l[i][j] = l[i - 1][j]; r[i][j] = r[i - 1][j]; if(a[i] == b[j]) { dp[i][j]++; if(j == nl && l[i][j] == 0) l[i][j] = i; if(j == nr) r[i][j] = i; } if(dp[i][j - 1] > dp[i][j]) { dp[i][j] = dp[i][j - 1]; l[i][j] = l[i][j - 1]; r[i][j] = r[i][j - 1]; } } } } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); scanf("%s", s); int zx = 9, zd = 0; for(int i = 1; i <= 10; i++) b[i] = i - 1; for(int i = 0; i < n; i++) { a[i + 1] = s[i] - '0'; zx = min(zx, a[i + 1]); zd = max(zd, a[i + 1]); } solve(10); ansl = 1; ansr = 1; ans = dp[n][10]; for(int i = zx; i <= zd; i++) { for(int j = zx; j < i; j++) { cnt = 0; for(int a = 0; a <= j; a++) b[++cnt] = a; nl = cnt + 1; for(int a = i; a >= j; a--) b[++cnt] = a; nr = cnt; for(int a = i; a < 10; a++) b[++cnt] = a; solve(cnt); if(dp[n][cnt] > ans && l[n][cnt] && r[n][cnt]) { ans = dp[n][cnt]; ansl = l[n][cnt]; ansr = r[n][cnt]; } } } printf("%d %d %d\n", ans, ansl, ansr); } return 0; }