2023冲刺国赛模拟8
A. A
你大概能看到我发的单篇(无向图最小环问题)
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
int read(){
int x = 0; char c = getchar();
while(!isdigit(c))c = getchar();
do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
return x;
}
const int maxn = 3005, inf = 0x1f1f1f1f;
int n, m;
vector<int>g[maxn];
int len; ll ans;
int dis[maxn]; ll f[maxn];
queue<int>q;
void upd(int l, ll f){
if(len > l)len = l, ans = f;
else if(len == l)ans += f;
}
void bfs(int s){
for(int i = s + 1; i <= n; ++i)dis[i] = inf;
for(int i = s + 1; i <= n; ++i)f[i] = 0;
dis[s] = 0; f[s] = 1; q.push(s);
while(!q.empty()){
int x = q.front(); q.pop();
for(int v : g[x])if(v >= s){
if(dis[v] > dis[x] + 1){
dis[v] = dis[x] + 1;
f[v] = f[x];
q.push(v);
}else if(dis[v] == dis[x] + 1){
upd(dis[v] + dis[x] + 1, f[v] * f[x]);
f[v] += f[x];
}else if(dis[v] == dis[x])upd(dis[v] + dis[x] + 1, f[v] * f[x]);
}
}
}
int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
n = read(), m = read();
for(int i = 1; i <= m; ++i){
int u = read(), v = read();
g[u].push_back(v); g[v].push_back(u);
}
len = INT_MAX;
for(int i = 1; i <= n; ++i)bfs(i);
if(len & 1)ans /= 2;
printf("%lld\n",ans);
return 0;
}
B. B
这个啊,对每种字母维护出现位置,询问离线
枚举答案,左右端点分别排序双指针找对应位置,前缀和得到答案
有一小点细节。
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
int read(){
int x = 0; char c = getchar();
while(!isdigit(c))c = getchar();
do{x = x * 10 + (c ^ 48); c = getchar();}while(isdigit(c));
return x;
}
const int maxn = 1.5e6 + 55, inf = 0x3f3f3f3f;
char s[maxn];
int n, m, sum[maxn];
vector<int>pos[26];
vector<pii>L, R, tmp;
struct ANS{
int len; char x, y;
ANS(){len = 0;}
void upd(int l, char a, char b){
if(l > len)len = l, x = a, y = b;
else if(l == len){
if(a < x)x = a, y = b;
else if(a == x && b < y)y = b;
}
}
void print(){printf("%d %c%c\n",len, x, y);}
}ans[maxn];
int rl[maxn], rr[maxn], res[maxn];
int main(){
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
scanf("%s", s + 1); n = strlen(s + 1);
for(int i = 1; i <= n; ++i)pos[s[i] - 'a'].push_back(i);
m = read();
for(int i = 1; i <= m; ++i)L.push_back(pii(read(), i)), R.push_back(pii(read(), i));
sort(L.begin(), L.end()); sort(R.begin(), R.end());
for(int a = 0; a < 26; ++a)
for(int b = a + 1; b < 26; ++b){
if(!pos[a].size() && !pos[b].size())continue;
int pa = 0, pb = 0; tmp.clear();
while(pa < pos[a].size() && pb < pos[b].size()){
if(pos[a][pa] < pos[b][pb])tmp.push_back(pii(pos[a][pa], 0)), ++pa;
else tmp.push_back(pii(pos[b][pb], 1)), ++pb;
}
while(pa < pos[a].size())tmp.push_back(pii(pos[a][pa], 0)), ++pa;
while(pb < pos[b].size())tmp.push_back(pii(pos[b][pb], 1)), ++pb;
sum[0] = 1; for(int i = 1; i < tmp.size(); ++i)sum[i] = sum[i - 1] + (tmp[i].second ^ tmp[i - 1].second);
int p = 0;
for(int i = 0; i < m; ++i){
int l = L[i].first;
while(p < tmp.size() && tmp[p].first < l)++p;
rl[L[i].second] = p;
}
p = 0;
for(int i = 0; i < m; ++i){
int r = R[i].first;
while(p < tmp.size() && tmp[p].first <= r)++p;
rr[R[i].second] = p - 1;
}
for(int i = 1; i <= m; ++i)if(rl[i] <= rr[i] && rr[i] >= 0 && rl[i] < tmp.size()){
ans[i].upd(sum[rr[i]] - sum[rl[i]] + 1 - tmp[rl[i]].second, a + 'a', b + 'a');
ans[i].upd(sum[rr[i]] - sum[rl[i]] + 1 - (tmp[rl[i]].second ^ 1), b + 'a', a + 'a');
}
}
for(int i = 1; i <= m; ++i)ans[i].print();
return 0;
}
C. C
愚者之夜
\(lxl\) 良(du)心(liu) 数据结构