voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; }
int a[1003][1003]; int m, n, x, y; intmain(){ int t; read(t); while(t--){ read(m), read(n), read(x), read(y); for (int i = 0; i < m; ++i){ for (int j = 0; j < n; ++j){ read(a[i][j]); if (i == 0 && j != 0){ a[i][j] += a[i][j - 1]; } if (i != 0 && j == 0){ a[i][j] += a[i - 1][j]; } if (i != 0 && j != 0){ a[i][j] += a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1]; } } } int ans = 0, temp; x--, y--; for (int i = 0; i < m - x; ++i){ for (int j = 0; j < n - y; ++j){ temp = a[i + x][j + y]; if (i) temp -= a[i - 1][j + y]; if (j) temp -= a[i + x][j - 1]; if (i && j) temp += a[i - 1][j - 1]; ans = max(ans, temp); } } printf("%d\n", ans); } return0; }
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; }
structedge{ int v, w, c, ne; }ed[200005]; int head[N], dis[N], dis1[N], vis[N], cnt; inlinevoidinit(){ ms(head, -1); ms(dis, INF); ms(dis1, INF); ms(vis, 0); cnt = 0; } inlinevoidadd(int u, int v, int w, int c){ ed[cnt] = {v, w, c, head[u]}; head[u] = cnt++; }
priority_queue<P, vector<P>, greater<P> > q;
voiddijk(int u){ dis[u] = 0; dis1[u] = 0; q.push(P(0, u)); while(!q.empty()){ u = q.top().second; q.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; ~i; i = ed[i].ne){ int v = ed[i].v, w = ed[i].w, c = ed[i].c; // 维护dis 和 dis1 if (dis[v] > dis[u] + w){ dis[v] = dis[u] + w; dis1[v] = dis1[u] + c; q.push(P(dis[v], v)); } elseif (dis[v] == dis[u] + w){ dis1[v] = min(dis1[v], dis1[u] + c); q.push(P(dis[v], v)); }
} } }
int n, m, u, v, w, c, s, t; intmain(){ while(~scanf("%d%d", &n, &m)){ if (m == 0 && n == 0) break; init(); for (int i = 0; i < m; ++i){ read(u), read(v), read(w), read(c); add(u, v, w, c); add(v, u, w, c); } read(s), read(t); dijk(s); cout << dis[t] << ' ' << dis1[t] << "\n"; }
ll read(){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } return x * w; } int a[N], b[N], c[N], d[N * 3], num[N]; int len;
inlineintf(int x){ return lower_bound(d + 1, d + len + 1, x) - d; } intmain(){ int n, m; n = read(); for (int i = 1; i <= n; ++i) a[i] = read(); m = read(); for (int i = 1; i <= m; ++i) b[i] = read(); for (int i = 1; i <= m; ++i) c[i] = read(); for (int i = 1; i <= n; ++i) d[++len] = a[i]; for (int i = 1; i <= m; ++i) d[++len] = b[i]; for (int i = 1; i <= m; ++i) d[++len] = c[i]; sort(d + 1, d + len + 1); len = unique(d + 1, d + len + 1) - (d + 1); for (int i = 1; i <= n; ++i) num[f(a[i])]++; int mx1 = -1, mx2 = -1, id; for (int i = 1; i <= m; ++i){ b[i] = f(b[i]) ,c[i] = f(c[i]); if (mx1 < num[b[i]] || mx1 == num[b[i]] && mx2 < num[c[i]]){ mx1 = num[b[i]]; mx2 = num[c[i]]; id = i; } } cout << id << "\n"; return0; }
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; }
int n, m, a, b, in[102]; vector<int>ve[N]; queue<int>q; vector<int>ans; inlinevoidinit(){ for (int i = 0; i <= n; ++i){ ve[i].clear(); in[i] = 0; ans.clear(); } }
intmain(){ while(~scanf("%d%d", &n, &m) && (m || n)){ init(); while(m--){ read(a), read(b); ve[a].push_back(b); in[b]++; } for (int i = 1; i <= n; ++i){ if (in[i] == 0) q.push(i); } while(!q.empty()){ int u = q.front(); q.pop(); ans.push_back(u); for (int i = 0; i < ve[u].size(); ++i){ int v = ve[u][i]; in[v]--; if(in[v] == 0) q.push(v); } } for (int i = 0; i < ans.size() - 1; ++i) cout << ans[i] << " "; cout << ans.back() << "\n"; } return0; }
E HDU 4578 【The__Flash】的操作
1. 题目大意
裸线段树, 就是有些许麻烦。4个操作
1 2 3 4
1 x y c 将[x, y]区间的数加c 2 x y c 将[x, y]区间的数乘c 3 x y c 将[x, y]区间的数重置为c 4 x y p 输出[x, y]区间的数的 p次方和
voidupdate(int op, int L, int R, int c, int l, int r, int rt){ if (l >= L && r <= R) { if (op == 3) { sett[rt] = c; add[rt] = 0; mul[rt] = 1; sum[rt] = ((r - l + 1) % mod * c) % mod; sum2[rt] = ((r - l + 1) % mod * ((c * c) % mod)) % mod; sum3[rt] = ((r - l + 1) % mod * (((c * c) % mod) * c % mod)) % mod; } elseif (op == 2) { mul[rt] = (mul[rt] * c) % mod; add[rt] = (add[rt] * c) % mod; sum[rt] = (sum[rt] * c) % mod; sum2[rt] = sum2[rt] * (c * c % mod) % mod; sum3[rt] = sum3[rt] * ((c * c % mod) * c % mod) % mod; } elseif (op == 1) { add[rt] = (add[rt] + c) % mod; int tmp = (((c * c) % mod * c) % mod * (r - l + 1) % mod) % mod; sum3[rt] = (sum3[rt] + tmp + 3 * c * sum2[rt] % mod + 3 * c * c % mod * sum[rt]) % mod; sum2[rt] = (sum2[rt] + (c * c % mod * ((r - l + 1) % mod)) % mod + 2 * sum[rt] * c % mod) % mod; sum[rt] = (sum[rt] + (r - l + 1) % mod * c % mod) % mod; }
return; } pushdown(rt, r - l + 1); int m = l + r >> 1; if (m >= L) update(op, L, R, c, l, m, rt << 1); if (m < R) update(op, L, R, c, m + 1, r, rt << 1 | 1); pushup(rt); }
intquery(int L, int R, int p, int l, int r, int rt){ if (l >= L && r <= R) { if (p == 1) return sum[rt]; if (p == 2) return sum2[rt]; if (p == 3) return sum3[rt]; } pushdown(rt, r - l + 1); int ans = 0; int m = l + r >> 1; if (m >= L) ans = (ans + query(L, R, p, l, m, rt << 1)) % mod; if (m < R) ans = (ans + query(L, R, p, m + 1, r, rt << 1 | 1)) % mod; return ans; }
int n, m, op, x, y, c;
intmain(){ while (~scanf("%d%d", &n, &m)) { if (!m && !n) break; build(1, n, 1); while (m--) { op = read(), x = read(), y = read(), c = read(); if (op <= 3) update(op, x, y, c, 1, n, 1); else printf("%d\n", query(x, y, c, 1, n, 1)); } } return0; }
ll read(){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } return x * w; }
bool flag[N << 2]; int val[N << 2];
voidinit(){ ms(flag, true); ms(val, 0); }
voidupdate(int op, int L, int R, int c, int l, int r, int rt){ if (l >= L && r <= R && flag[rt]){ if (op == 1) val[rt] = (val[rt] + c) % mod; elseif (op == 2) val[rt] = (val[rt] * c) % mod; elseif (op == 3) val[rt] = c; return ; } if (flag[rt]){ // pushdown flag[rt << 1] = flag[rt << 1 | 1] = 1; flag[rt] = 0; val[rt << 1] = val[rt << 1 | 1] = val[rt]; } int m = l + (r - l) / 2; if (m >= L) update(op, L, R, c, l, m, rt << 1); if (m < R) update(op, L, R, c, m + 1, r, rt << 1 | 1); if (flag[rt << 1] && flag[rt << 1 | 1]){ if (val[rt << 1] == val[rt << 1 | 1]){ flag[rt] = 1; val[rt] = val[rt << 1]; } else flag[rt] = 0; } else flag[rt] = 0; }
intquery(int L, int R, int p, int l, int r, int rt){ if (l >= L && r <= R && flag[rt]){ int ans = 1; for (int i = 1; i <= p; ++i){ ans = (ans * val[rt]) % mod; } ans = ans * (r - l + 1) % mod; return ans; } if (flag[rt]){ flag[rt << 1] = flag[rt << 1 | 1] = 1; flag[rt] = 0; val[rt << 1] = val[rt << 1 | 1] = val[rt]; } int m = l + (r - l) / 2; int ans = 0; if (m >= L) ans += query(L, R, p, l, m, rt << 1) % mod; if (m < R) ans += query(L, R, p, m + 1, r, rt << 1 | 1) % mod; return ans % mod; } int n, m; intmain(){ while(~scanf("%d%d", &n, &m)){ if (n == 0 && m == 0) break; int x, y, op, c; init(); while(m--){ op = read(), x = read(), y = read(), c = read(); if (op <= 3) update(op, x, y, c, 1, n, 1); else printf("%d\n", query(x, y, c, 1, n, 1)); } } return0; }
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; } int a[N]; intmain(){ int n; read(n); int sum = 0; int flag = 100000; for (int i = 0; i < n; ++i){ read(a[i]); if (a[i] > 0){ sum += a[i]; } if (a[i] & 1) flag = min(flag, abs(a[i])); } if (sum & 1) cout << sum << "\n"; elsecout << sum - flag << "\n"; return0; }
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; }
string a, b; set<char>se; intmain(){ int t; read(t); while(t--){ se.clear(); cin >> a >> b; for (int i = 0; i < a.length(); ++i) se.insert(a[i]); int flag = 0; for (int i = 0; i < b.length(); ++i){ if (se.find(b[i]) != se.end()){ flag = 1; break; } } if (flag) puts("YES"); elseputs("NO"); } return0; }
H CodeForces 960B 【The__Flash】的赠予
1. 题目大意
给你两个序列a, b, 定义E = (ai - bi) ^ 2 | i : 1 - n , 每一次操作可以使序列中的某个数加1或者减1, 问对序列a进行k1次操作, b进行k2次操作后E的最小值。
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; } priority_queue<int> q; int a[1003], b[1003]; intmain(){ int n, k1, k2; read(n), read(k1), read(k2); for (int i = 0; i < n; ++i) read(a[i]); for (int i = 0; i < n; ++i){ read(b[i]); q.push(abs(a[i] - b[i])); } int k = k1 + k2; while(k--){ int u = q.top(); q.pop(); q.push(abs(u - 1)); } ll ans = 0; while(!q.empty()){ int u = q.top(); q.pop(); ans += 1ll * u * u; // 注意会爆long long } cout << ans << "\n"; return0; }
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; }
structedge{ int v, w, ne; }ed[M];
int head[N], vis[N], cnt; ll dis[N]; int n, m, a, b; inlinevoidinit(){ for (int i = 0; i <= n; ++i){ head[i] = -1, vis[i] = 0, dis[i] = llINF; } cnt = 0; }
inlinevoidadd(int u, int v, int w){ ed[cnt] = {v, w, head[u]}; head[u] = cnt++; }
priority_queue<P, vector<P> , greater<P> >q; voiddijk(int u){ dis[u] = 0; q.push(P(0, u)); while(!q.empty()){ u = q.top().second; q.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; ~i; i = ed[i].ne){ int v = ed[i].v, w = ed[i].w; if (dis[v] > dis[u] + w){ dis[v] = dis[u] + w; q.push(P(dis[v], v)); } } } }
intmain(){ int u, v, dis1n, in1, in2; while(~scanf("%d%d%d%d", &n, &m, &a, &b)){ init(); dis1n = b; in1 = in2 = 0; while(m--){ read(u), read(v); if (u > v) swap(u, v); add(u, v, a); add(v, u, a); if (u == 1) in1++; if (v == n) in2++; if (u == 1 && v == n) dis1n = a; } if (a <= b){ if (dis1n == a) cout << a << "\n"; else{ dijk(1); if (dis[n] <= b) cout << dis[n] << "\n"; elsecout << b << "\n"; } } else{ if (dis1n == b){ cout << b << "\n"; continue; } int sum = 0; if (in1 == n - 1) sum++; if (in2 == n - 1) sum++; if (sum >= 1) cout << a << "\n"; elsecout << min(a, 2 * b) << "\n"; } } }
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; }
int n, l, r; int diff[N], ans[N]; intmain(){ while(~scanf("%d", &n) && n){ ms(diff, 0); for (int i = 0; i < n; ++i){ read(l), read(r); diff[l] ++; diff[r + 1]--; } int add = 0; for (int i = 1; i <= n; ++i){ add += diff[i]; ans[i] = add; } for (int i = 1; i < n; ++i) cout << ans[i] << " "; cout << ans[n] << "\n"; }
constint N = 1e5 + 5; constint M = 1e6 + 5; constint INF = 0x3f3f3f3f; const ll llINF = 4611686018427387903; constint mod = 998244353;
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; } int n, k; double sum[N]; int a[N]; inlineboolis(double x){ for (int i = 1; i <= n; ++i) sum[i] = a[i] - x; for (int i = 1; i <= n; ++i) sum[i] += sum[i - 1]; double mi = INF * 1.0; for(int i = k; i <= n; ++i){ mi = min(mi, sum[i - k]); if (sum[i] - mi >= -eps) // 特别注意这里。。 return1; } return0; }
intmain(){ read(n), read(k); for (int i = 1; i <= n; ++i){ read(a[i]); } int l = 0, r = 2000000, m; while(l < r){ m = l + (r - l + 1) / 2; if (is(1.0 * m / 1000)) l = m; else r = m - 1; } cout << l << "\n"; return0; }
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; } int n, k; int sum[N]; int a[N]; double rsum[N]; inlineboolis(double x){ rsum[n] = a[n] - x; for (int i = n - 1; i >= 1; --i){ rsum[i] = a[i] - x; if (rsum[i + 1] > 0) rsum[i] += rsum[i + 1]; } for (int i = 1; i <= n - k + 1; ++i){ if (sum[i + k - 1] - sum[i - 1] >= x * k) returntrue; if (sum[i + k - 1] - sum[i - 1] - x * k + rsum[i + k] >= 0) returntrue; } returnfalse; }
intmain(){ read(n), read(k); for (int i = 1; i <= n; ++i){ read(a[i]); sum[i] = sum[i - 1] + a[i]; } int l = 0, r = 2000000, m; while(l < r){ m = l + (r - l + 1) / 2; if (is(1.0 * m / 1000)) l = m; else r = m - 1; } cout << l << "\n";
return0; }
4. 后继
知道如何在O(n)求 长度至少为k的 区间和的最大值
L CodeForces 621B 【The__Flash】的鲨鲨
1. 题目大意
1000 * 1000 的网格中, 处于对角线上的鲨鲨会互相打架, 求有对少对鲨鲨会打架。
2. 分析
画图可分析, 处于对角线上的鲨鲨满足 x + y = t (0<= t <= 2000) 或者满足 x - y = t (-1000 <= t <= 1000), 分别用两个数组储存在每一条对角线上的个数, 然后n * (n - 1) / 2 计算即可, 注意x - y的范围, 可以化成 x - y + 1000 = t (0 <= t <= 2000) , 因为这个我re了两次QAQ
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; }
structnode{ int hp, atk; double v; }a[N];
boolcmp(node x, node y){ if (fabs(x.v - y.v) <= eps) return x.hp > y.hp; return x.v > y.v; } int a1[10003], a2[10003]; intmain(){ int n, x, y; read(n); for (int i = 0; i < n; ++i){ read(x), read(y); a1[x + y]++; a2[x - y + 1000]++; } ll ans = 0; for (int i = 0; i <= 2000; ++i){ if (a1[i] > 1){ ans += ll(a1[i]) * ll(a1[i] - 1) / 2; } if (a2[i] > 1){ ans += ll(a2[i]) * ll(a2[i] - 1) / 2; } } cout << ans << "\n"; return0; }
voidread(int &ans){ ll x = 0, w = 1; char ch = 0; while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + (ch - '0'); ch = getchar(); } ans = x * w; }