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;
}

posted @ 2020-09-06 14:52  harryhqg  阅读(191)  评论(2编辑  收藏  举报