https://ac.nowcoder.com/acm/contest/700#question
I
dp思想,维护以(i, j)为左上端点,长宽为k的矩形内最大值和最小值,dp[i][j] = min{dp[i][j], dp[i+1][j], dp[i][j+1], dp[i+1][j+1]}
#include <bits/stdc++.h>
using namespace std;
const int maxn = 500 + 5;
int a[maxn][maxn];
int minn[maxn][maxn], maxx[maxn][maxn];
int min_4(int a, int b, int c, int d) {
return min(a, min(b, min(c, d)));
}
int max_4(int a, int b, int c, int d) {
return max(a, max(b, max(c, d)));
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, m, g;
cin >> n >> m >> g;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
cin >> a[i][j], minn[i][j] = maxx[i][j] = a[i][j];
int ans = 1;
for(int k = 2; k <= min(n, m); ++k) {
for(int i = 1; i <= n; ++i) if(i + k - 1 <= n) {
for(int j = 1; j <= m; ++j) if(j + k - 1 <= m) {
minn[i][j] = min_4(minn[i][j], minn[i + 1][j], minn[i][j + 1], minn[i + 1][j + 1]);
maxx[i][j] = max_4(maxx[i][j], maxx[i + 1][j], maxx[i][j + 1], maxx[i + 1][j + 1]);
if(maxx[i][j]- minn[i][j] <= g && ans < k) ans = k;
}
}
}
cout << ans << endl;
}
J
对于一个集合S,如果S中的数可以凑出mx,那么如果向集合S中新添加一个数x,若x<=mx+1,那么加入x后S可以凑出0~mx+x的所有数,但如果x>mx+1,则x对扩大可凑出的数的范围没有作用。
排序后按次序维护
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 4;
ll arr[maxn];
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; ++i) scanf("%lld", &arr[i]);
ll mx = 0;
sort(arr, arr + n);
for(int i = 0; i < n; ++i) {
if(arr[i] <= mx + 1) mx = max(mx, mx + arr[i]);
else {
printf("%lld\n", mx + 1);
return 0;
}
}
cout << mx + 1 << endl;
}
H
最短路,优先队列+pair优化代码
#include <bits/stdc++.h>
#define pi pair<int, int>
using namespace std;
const int maxn = 3e5 + 5;
const int inf = 0x3f3f3f3f;
map<string, int> id;
int n, tot, cnt[maxn];
vector<pair<pi, int>> E[maxn];
int getid(string s) {
if(id.find(s) == id.end()) {
id[s] = ++tot;
int length = s.length(), vowel = 0;
for(int i = 0; i < length; ++i) {
if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u')
vowel++;
}
E[0].push_back(make_pair(pi(vowel, length), tot));
}
return id[s];
}
pi d[maxn];
priority_queue<pair<pi, int>, vector<pair<pi, int>>, greater<pair<pi, int>> >Q;
void Spfa() {
for(int i = 0; i <= tot; ++i) d[i] = pi(inf, 0);
d[0] = pi(0, 0);
Q.push(make_pair(d[0], 0));
while(!Q.empty()) {
int u = Q.top().second; Q.pop();
for(int i = 0; i < E[u].size(); ++i) {
int v = E[u][i].second;
if(pi(d[u].first + E[u][i].first.first, d[u].second + E[u][i].first.second) < d[v]) {
d[v] = pi(d[u].first + E[u][i].first.first, d[u].second + E[u][i].first.second);
Q.push(make_pair(d[v], v));
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
string s1, s2;
for(int i = 0; i < n; ++i) {
cin >> s1;
int node = getid(s1);
cnt[node]++;
}
int m;
cin >> m;
for(int i = 0; i < m; ++i) {
cin >> s1 >> s2;
int u = getid(s1), v = getid(s2);
E[v].push_back(make_pair(pi(0, 0), u));
}
Spfa();
long long x = 0, y = 0;
for(int i = 1; i <= tot; ++i) {
x += 1ll * cnt[i] * d[i].first;
y += 1ll * cnt[i] * d[i].second;
}
cout << x << " " << y << endl;
}
C
前缀和+树状数组维护
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
int tre[maxn], m;
ll pre[maxn], mp[maxn];
void add(int x, int v) {
while(x <= m) {
tre[x] += v;
x += (x & -x);
}
}
int query(int x) {
int sum = 0;
while(x) {
sum += tre[x];
x -= (x & -x);
}
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, l, r;
ll s;
cin >> n >> l >> r >> s;
for(int i = 1; i <= n; ++i) {
cin >> pre[i];
pre[i] += pre[i - 1];
mp[i] = pre[i];
}
sort(mp + 1, mp + n + 1);
m = unique(mp + 1, mp + n + 1) - mp - 1;
for(int i = 1; i <= n; ++i) {
pre[i] = lower_bound(mp + 1, mp + m + 1, pre[i]) - mp;
}
for(int i = l; i <= r; ++i)
add(pre[i], 1);
ll ans = 0;
for(int i = 1; i <= n; ++i) {
int pos = lower_bound(mp + 1, mp + m + 1, s + mp[pre[i - 1]]) - mp - 1;
ans += query(m) - query(pos);
add(pre[l++], -1);
if(r < n) add(pre[++r], 1);
if(l > n) break;
}
cout << ans << endl;
}