HGOI 20200906
9月了,时间不多了,写写博客记录生活
今天虽然A了一题,但是其他两题都接近0分,总分不好啊
T1
这个大模拟!
开始看错题了
以为要写编译器果断切题
切了T2后仔细一看woc原来就是图+模拟
懵了
写完了但0分
血亏
就一个模拟+记搜就行了
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define siz(a) (int)a.size()
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second
const int N = 100010 ;
int n ;
signed main() {
int T; scanf("%d", &T) ;
while (T--) {
bool segmentation_fault = false;
bool compile_error = false;
map<string, unsigned ll> fn;
set<string> seg;
scanf("%d", &n) ;
string s;
for (int i = 0; i <= 3; i++) getline(cin, s);
fn["A"] = 1;
fn["printf"] = 0;
for (int cnt = 3; cnt < n;) {
getline(cin, s);
cnt++;
stringstream sss;
sss << s;
sss >> s;
while (sss.peek() == ' ') sss.get();
getline(sss, s, '(');
if (fn.count(s)) compile_error = true;
const string func = s;
const map<string, unsigned ll>::iterator it = fn.insert({ s, 0 }).first;
if (func == "main") {
getline(cin, s);
cnt++;
}
while (cnt < n) {
getline(cin, s);
cnt++;
if (s == "}") break;
stringstream ss;
ss.clear();
ss << s;
while (ss.peek() == ' ') ss.get();
getline(ss, s, '(');
if (s == func || seg.count(s)) {
seg.insert(func);
if (func == "main") segmentation_fault = true;
}
if (!fn.count(s)) compile_error = true;
else it->second += fn[s];
}
}
if (compile_error) cout << "Compile error\n";
else if (segmentation_fault) cout << "Segmentation fault\n";
else cout << fn["main"] << '\n';
}
return 0;
}
T2
A了这题!
算法都不难,合一起就容易错
先求出最短路图
然后在对短路上求概率
p[i][j]表示第i个势力到第j个位置的概率
考虑求出每个位置的答案
逆向思维
ans[i]=1-没有人经过此地-一个势力的两只队伍同时经过此地
前者很明显就是(1-p[][i])的累乘
后者就是累乘扣掉某一个(1-p[k][i])再乘p[k][i]
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
#define siz(a) (int)a.size()
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second
const int N = 3010 ;
const int mod = 998244353 ;
int n, m, k, cnt, sz ;
int head[N], heads[N], headn[N] ;
int deg[N], vis[N], dis[N], pf[N] ;
int inv[N], pp[N], ps[N], ans[N] ;
int p[N][N << 2] ;
struct Edge {
int to, nxt ;
} e[N << 2], es[N << 2], en[N << 2] ;
void add(int a, int b) {
e[++cnt].to = b ; e[cnt].nxt = head[a] ; head[a] = cnt ;
}
void addedge(int a, int b) {
es[++cnt].to = b ; es[cnt].nxt = heads[a] ; heads[a] = cnt ;
en[cnt].to = a ; en[cnt].nxt = headn[b] ; headn[b] = cnt ;
deg[b]++ ;
}
queue <int> q ;
void spfa(int a) {
while (!q.empty()) q.pop() ;
q.push(a) ; dis[a] = 0 ;
while (!q.empty()) {
int u = q.front() ; q.pop() ;
vis[u] = 0 ;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to ;
if (dis[v] > dis[u] + 1) {
dis[v] = dis[u] + 1 ;
if (!vis[v]) {
vis[v] = 1 ;
q.push(v) ;
}
}
}
}
}
void get() {
cnt = 0 ;
memset(heads, 0, sizeof(heads)) ;
memset(headn, 0, sizeof(headn)) ;
memset(deg, 0, sizeof(deg)) ;
rep(i, 1, n)
for (int j = head[i]; j; j = e[j].nxt)
if (dis[i] + 1 == dis[e[j].to]) addedge(i, e[j].to) ;
}
void rev(int b) {
memset(vis, 0, sizeof(vis)) ;
while (!q.empty()) q.pop() ;
q.push(b) ; vis[b] = 1 ;
while (!q.empty()) {
int u = q.front() ; q.pop() ;
for (int i = headn[u]; i; i = en[i].nxt)
if (!vis[en[i].to]) {
vis[en[i].to] = 1 ;
q.push(en[i].to) ;
}
}
}
void calc(int c, int a) {
int tot = 0 ;
memset(pf, 0, sizeof(pf)) ;
while (!q.empty()) q.pop() ;
q.push(a) ; pf[a] = 1 ;
while (!q.empty()) {
int u = q.front() ; q.pop() ;
tot = 0 ;
for (int i = heads[u]; i; i = es[i].nxt)
if (deg[es[i].to] && vis[es[i].to]) tot++ ;
for (int i = heads[u]; i; i = es[i].nxt)
if (vis[es[i].to] && deg[es[i].to]) {
int v = es[i].to ;
deg[v]-- ;
pf[v] = (pf[v] + pf[u] * inv[tot] % mod) % mod ;
if (!deg[v]) q.push(v) ;
}
}
rep(i, 1, n) p[c][i] = p[c][i] * ((1 - pf[i] + mod) % mod) % mod ;
}
signed main() {
// freopen("sukeban.in", "r", stdin) ;
// freopen("sukeban.out", "w", stdout) ;
inv[0] = inv[1] = 1 ;
rep(i, 2, 1000) inv[i] = (mod - mod / i) * inv[mod % i] % mod ;
int t ; scanf("%lld", &t) ;
while (t--) {
memset(head, 0, sizeof(head)) ;
cnt = 0 ;
scanf("%lld%lld%lld", &n, &m, &k) ;
rep(i, 1, m) {
int x, y ; scanf("%lld%lld", &x, &y) ;
add(x, y) ; add(y, x) ;
}
rep(j, 1, n) rep(i, 1, k) p[i][j] = 1 ;
sz = 0 ;
rep(i, 1, k) {
int c, a, b ; scanf("%lld%lld%lld", &c, &a, &b) ;
sz = max(sz, c) ;
memset(dis, 0x3f, sizeof(dis)) ;
memset(vis, 0, sizeof(vis)) ;
spfa(a) ;
get() ;
rev(b) ;
calc(c, a) ;
}
memset(ans, 0, sizeof(ans)) ;
rep(i, 1, n) {
pp[0] = ps[sz + 1] = 1ll ;
rep(j, 1, sz) pp[j] = pp[j - 1] * p[j][i] % mod ;
per(j, sz, 1) ps[j] = ps[j + 1] * p[j][i] % mod ;
ans[i] = ps[1] ;
rep(j, 1, sz) ans[i] = (ans[i] + pp[j - 1] * ps[j + 1] % mod * (1 - p[j][i] + mod) % mod) % mod ;
printf("%lld\n", (1 - ans[i] + mod) % mod) ;
}
}
return 0 ;
}
T3
还不会
O(N^3)会不想写
复制solution+std
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstdlib>
#define LL long long
#define LD long double
using namespace std;
const int NN = 30000 + 117;
const int SQRTN = 200;
const int MM = +117;
int read() {
int fl = 1, x;
char c;
for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
;
if (c == '-') {
fl = -1;
c = getchar();
}
for (x = 0; c >= '0' && c <= '9'; c = getchar()) x = (x << 3) + (x << 1) + c - '0';
return x * fl;
}
void open() {
freopen("ex_mito2.in", "r", stdin);
// freopen("mito.out","w",stdout);
}
void close() {
fclose(stdin);
fclose(stdout);
}
int m, n;
struct node {
int f, r;
int pos;
} a[NN];
bool cmp(node a, node b) {
if (a.f != b.f)
return a.f < b.f;
if (a.r != b.r)
return a.r < b.r;
return a.pos < b.pos;
}
vector<int> ls;
struct edge {
int to, len;
edge(int t = 0, int l = 0) { to = t, len = l; }
};
vector<edge> p[NN * SQRTN];
int pcnt;
int pt[NN] = {};
void build(int f, int rem) {
for (int i = rem; i < n; i += f) {
++pcnt;
pt[i] = pcnt;
}
for (int i = rem; i < n; i += f) {
if (i - f >= 0)
p[pt[i]].push_back(edge(pt[i - f], 1));
if (i + f < n)
p[pt[i]].push_back(edge(pt[i + f], 1));
}
int pos = 0;
for (int i = rem; i < n; i += f) {
while (pos != ls.size() && ls[pos] < i) ++pos;
int dis = 1e9;
if (pos != ls.size())
dis = min(dis, (ls[pos] - i) / f);
if (pos)
dis = min(dis, (i - ls[pos - 1]) / f);
p[i].push_back(edge(pt[i], dis));
p[pt[i]].push_back(edge(i, 0));
}
/*
for(int i=0;i<ls.size();++i){
int k=ls[i];
p[k].push_back(edge(pt[k],0));
}
*/
}
struct spnode {
int pt, dis;
spnode(int p = 0, int d = 0) { pt = p, dis = d; }
};
struct spcmp {
bool operator()(spnode a, spnode b) { return a.dis > b.dis; }
};
priority_queue<spnode, vector<spnode>, spcmp> q;
int sp[NN * SQRTN] = {};
void getsp(int st) {
for (int i = 0; i <= pcnt; ++i) {
sp[i] = 1e9;
}
sp[st] = 0;
q.push(spnode(st, 0));
while (!q.empty()) {
if (sp[q.top().pt] < q.top().dis) {
q.pop();
continue;
}
int x = q.top().pt;
q.pop();
for (int i = 0; i < p[x].size(); ++i) {
int cur = p[x][i].to;
if (sp[cur] > sp[x] + p[x][i].len) {
sp[cur] = sp[x] + p[x][i].len;
q.push(spnode(cur, sp[cur]));
}
}
}
}
int main() {
open();
n = read();
m = read();
for (int i = 1; i <= m; ++i) {
a[i].pos = read();
a[i].f = read();
a[i].r = a[i].pos % a[i].f;
}
int start = a[1].pos;
int final = a[2].pos;
int freq = a[2].f;
sort(a + 1, a + 1 + m, cmp);
ls.push_back(a[1].pos);
int nf = a[1].f;
int nr = a[1].r;
pcnt = n;
for (int i = 2; i <= m + 1; ++i) {
if (a[i].f == nf && a[i].r == nr) {
ls.push_back(a[i].pos);
} else {
build(nf, nr);
nf = a[i].f;
nr = a[i].r;
ls.clear();
ls.push_back(a[i].pos);
}
}
getsp(start);
int ans = 1e9;
for (int i = final % freq; i < n; i += freq) {
ans = min(ans, (sp[i] + abs(i - final) / freq));
}
/*ans=sp[final];*/
if (ans >= 1e8)
printf("-1\n");
else
printf("%d\n", ans);
close();
return 0;
}
加油ヾ(◍°∇°◍)ノ゙