zoukankan      html  css  js  c++  java
  • 联赛模拟测试 32 题解

    前言:

    为了应付skyh的检查,鸽子博主被迫再次写题解

    T1 : 循环依赖

    一眼sb题,判断一下有没有环即可,就是读入有点恶心
    代码实现

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <map>
    using namespace std;
    const int maxn = 5e5 + 50;
    inline int read () {
    	int x = 0, f = 1; char ch = getchar();
    	for (;!isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
    	for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    	return x * f;
    }
    map <unsigned long long, unsigned long long> mp;
    int cnt, T , n;
    unsigned long long base, now;
    char S[20], C;
    unsigned long long gethash (char S[]) {
    	int len = strlen (S + 1);
    	unsigned long long Hash = 0;
    	for (register int i = 1; i <= len; i++) {
    		Hash *= 233;
    		Hash += S[i];
    	}
    	return Hash;
    }
    struct Edge {
    	int to, next;
    } edge[maxn];
    int tot, head[maxn];
    void addedge (int a, int b) {
    	edge[++tot].to = b;
    	edge[tot].next = head[a];
    	head[a] = tot;
    }
    int stk[maxn], top, dfn_clock;
    int belong[maxn], low[maxn], dfn[maxn], scc_cnt, siz[maxn];
    int sta[maxn], tp;
    void tarjan (int u) {
    	low[u] = dfn[u] = ++dfn_clock;
    	sta[++tp] = u;
    	for (register int i = head[u]; i; i = edge[i].next) {
    		int v = edge[i].to;
    		if (!dfn[v]) {
    			tarjan (v);
    			low[u] = min(low[u], low[v]);
    		} else if (!belong[v]) {
    			low[u] = min (low[u], dfn[v]);
    		}
    	}
    	if (dfn[u] == low[u]) {
    		++scc_cnt;
    		while (1) {
    			int x = sta[tp--];
    			belong[x] = scc_cnt;
    			siz[scc_cnt]++;
    			if (x == u) break;
    		}
    	}
    }
    bool judge;
    int main () {
    	freopen ("dependency.in", "r", stdin);
    	freopen ("dependency.out", "w", stdout);
    	T = read();
    	while (T--) {
    		n = read();
    		judge = false;
    		for (register int i = 1; i <= n; i++) {
    			scanf ("%s", S + 1);
    			C = getchar();
    			base = gethash(S);
    			if (mp[base] == 0) mp[base] = ++cnt;
    			base = mp[base], stk[++top] = base;
    			while (1) {
    				if (C == '
    ') break;
    				scanf ("%s", S + 1);
    				now = gethash(S);
    				if (mp[now] == 0) mp[now] = ++cnt;
    				now = mp[now];
    				addedge (base, now);
    				if (base == now) {
    					judge = true;
    				}
    				stk[++top] = now;
    				C = getchar();
    			}
    		}
    		for (register int i = 1; i <= top; i++) {
    			if (dfn[stk[i]]) continue;
    			tarjan (stk[i]);
    		}
    		for (register int i = 1; i <= scc_cnt; i++) {
    			if (siz[i] > 1) {
    				judge = true;
    			}
    		}
    		if (judge == true) {
    			puts("Yes");
    		} else {
    			puts("No");
    		}
    		tot = 0;
    		scc_cnt = 0;
    		for (register int i = 1; i <= top; i++) {
    			belong[stk[i]] = 0;
    			siz[i] = 0;
    			low[stk[i]] = dfn[stk[i]] = 0;
    			head[stk[i]] = 0;
    			sta[i] = 0;
    		}
    		tp = 0;
    		top = 0;
    		dfn_clock = 0;
    	}
    	return 0;
    }
    
    

    T2 : A

    维护一个凸包
    在 x > 0 的时候就让 ax + b 取最大, 在x < 0 的时候就让ax + b 取最小
    维护两个凸包就好了,注意向哪儿取整的问题
    代码实现

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define int long long
    const int maxn = 5e5 + 50;
    inline int read () {
    	int x = 0, f = 1; char ch = getchar();
    	for (;!isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
    	for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    	return x * f;
    }
    int n, q;
    int top1, top2;
    struct Node {
    	int l;
    	int a, b;
    } stk1[maxn], stk2[maxn];
    struct Line {
    	int a, b;
    } line[maxn];
    struct Ask {
    	int id, x;
    	long long val;
    } ask[maxn];
    long long ans[maxn];
    inline bool cmp1 (Line A, Line B) {return A.a == B.a ? A.b < B.b : A.a > B.a;}
    inline bool cmp2 (Line A, Line B) {return A.a == B.a ? A.b > B.b : A.a < B.a;}
    inline bool Cmp  (Ask A, Ask B) {return A.x < B.x;}
    inline int getx (int a, int b, int c, int d) {
    	if ((d - b) % (a - c) == 0) {
    		return (d - b) / (a - c);
    	}
    	if ((d - b) / (a - c) < 0) return (d - b) / (a - c);
    	else return (d - b) / (a - c) + 1;
    }
    signed main () {
    	freopen ("A.in", "r", stdin);
    	freopen ("A.out", "w", stdout);
    	n = read(), q = read();
    	for (register int i = 1; i <= n; i++) {
    		line[i].a = read(), line[i].b = read();
    	}
    	//上凸
    	sort (line + 1, line + 1 + n, cmp1);
    	stk1[++top1].a = line[1].a;
    	stk1[top1].b = line[1].b;
    	stk1[top1].l = -0x3f3f3f3f;
    	for (register int i = 2; i <= n; i++) {
    		if (line[i].a == stk1[top1].a) continue;
    		int x = getx (line[i].a, line[i].b, stk1[top1].a, stk1[top1].b);
    		while (x <= stk1[top1].l) {
    			top1--;
    			x = getx (line[i].a, line[i].b, stk1[top1].a, stk1[top1].b);
    		}
    		++top1;
    		stk1[top1].a = line[i].a, stk1[top1].b = line[i].b, stk1[top1].l = x;
    	}
    	//下凸
    	sort (line + 1, line + 1 + n, cmp2);
    	stk2[++top2].a = line[1].a;
    	stk2[top2].b = line[1].b;
    	stk2[top2].l = -0x3f3f3f3f;
    	for (register int i = 2; i <= n; i++) {
    		if (line[i].a == stk2[top2].a) continue;
    		int x = getx (line[i].a, line[i].b, stk2[top2].a, stk2[top2].b);
    		while (x <= stk2[top2].l) {
    			top2--;
    			x = getx (line[i].a, line[i].b, stk2[top2].a, stk2[top2].b);
    		}
    		++top2;
    		stk2[top2].a = line[i].a, stk2[top2].b = line[i].b, stk2[top2].l = x;
    	}
    	for (register int i = 1; i <= q; i++) {
    		ask[i].x = read();
    		ask[i].id = i;
    	}
    	sort (ask + 1, ask + 1 + q, Cmp);
    	int oper = 1;
    	int r = 1;
    	while (ask[oper].x < 0) {
    		while (stk1[r + 1].l <= ask[oper].x && r < top1) r++;
    		ans[ask[oper].id] = ask[oper].x * ask[oper].x * stk1[r].a + ask[oper].x * stk1[r].b;
    		oper++;
    	}
    	r = 1;
    	while (oper <= q) {
    		while (stk2[r + 1].l <= ask[oper].x && r < top2) r++;
    		ans[ask[oper].id] = ask[oper].x * ask[oper].x * stk2[r].a + ask[oper].x * stk2[r].b;
    		oper++;
    	}
    	for (register int i = 1; i <= q; i++) {
    		printf ("%lld
    ", ans[i]);
    	}
    	return 0;
    }
    

    T3 : B

    都是1的情况找规律就好了,1, 2, 4 的数据点可以记忆化一下。
    代码实现

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int maxn = 5e5 + 5, mod = 323232323;
    inline int read () {
    	int x = 0, f = 1; char ch = getchar();
    	for (;!isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
    	for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    	return x * f;
    }
    int n, a[maxn], p[maxn], s, inv[maxn], mx, f[10000000];
    bool g = 1;
    
    int Dfs(int S) {
    	int tot = 0, &s = f[S];
    	if (s) return s;
    	if (S % p[1] == 0) return 0;
    	for (int i = 1; i <= n; ++i) {
    		int x = S % p[i] / p[i-1];
    		if (!x) continue;
    		tot++;
    		if ((s += Dfs(S - p[i-1]) + 1) >= mod) s -= mod;
    	}
    	return s = 1LL * s * inv[tot] % mod;
    }
    
    int main() {
    	freopen("B.in", "r", stdin), freopen("B.out", "w", stdout);
    	n = read();
    	for (int i = 1; i <= n; ++i) {
    		a[i] = read();
    		if (a[i] > mx) mx = a[i];
    		if (a[i] != 1) g = 0;
    	}
    	mx++;
    	p[0] = inv[1] = 1;
    	for (int i = 2; i <= n; ++i)
    		inv[i] = 1LL * (mod - mod / i) * inv[mod%i] % mod;
    	for (int i = 1; i <= n; ++i) {
    		p[i] = p[i-1] * mx;
    		s += a[i] * p[i-1];
    	}
    	if (g) return printf("%lld
    ", 1LL * (n + 1) * inv[2] % mod), 0;
    	printf("%d
    ", Dfs(s));
    	return 0;
    }
    

    t4 : C

    不会第4个数据点和第8个数据点,但是貌似暴力跑过第8个数据点了?
    赛时没算内存然后炸了,草
    然后第四个数据点还是不会写,先咕了,等会了再向skyh报告
    然后扔个40分代码(逃)

    #include <bits/stdc++.h>
    using namespace std;
    inline int read() {
    	int k = 0, f = 1; char ch = getchar();
    	for (; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    	for (; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
    	return k * f;
    }
    const int maxn = 6e5 + 100;
    struct node { int to, next; } e[maxn];
    int head[maxn], ecnt = 0;
    void add(int u, int v) { e[++ecnt] = (node){v, head[u]}; head[u] = ecnt; }
    int size[maxn], depth[maxn], fa[maxn], top[maxn], a[maxn], son[maxn];
    void dfs1(int u, int f) {
    	size[u] = 1;
    	for (int i = head[u]; i; i = e[i].next) {
    		int v = e[i].to;
    		if (v == f) continue;
    		fa[v] = u;
    		depth[v] = depth[u] + 1;
    		dfs1(v, u);
    		size[u] += size[v];
    		if (size[u] > size[son[u]]) son[u] = v;
    	}
    }
    void dfs2(int u, int t) {
    	top[u] = t;
    	if (son[u]) dfs2(son[u], t);
    	for (int i = head[u]; i; i = e[i].next) {
    		int v = e[i].to;
    		if (v == fa[u] || v == son[u]) continue;
    		dfs2(v, v);
    	}
    }
    int lca(int u, int v) {
    	while (top[u] != top[v]) {
    		if (depth[top[u]] > depth[top[v]]) {
    			u = fa[top[u]];
    		} else {
    			v = fa[top[v]];
    		}
    	}
    	return depth[u] < depth[v] ? u : v;
    }
    struct edge { int u, v; } Q[maxn];
    int Ans[maxn];
    void dfs(int u, int f) {
    	for (int i = head[u]; i; i = e[i].next) {
    		int v = e[i].to;
    		depth[v] = depth[u] + 1;
    		Ans[v] = Ans[u] + (depth[v] | a[v]);
    		dfs(v, u);
    	}
    }
    int main() {
    	freopen("C.in", "r", stdin);
    	freopen("C.out", "w", stdout);
    	int n = read(), q = read(), flag = 0;
    	for (int i = 1; i <= n; i++) a[i] = read();
    	for (int i = 1; i < n; i++) {
    		int u = read(), v = read();
    		add(u, v), add(v, u);
    	}
    	for (int i = 1; i <= q; i++) {
    		Q[i].u = read(), Q[i].v = read();
    		if (Q[i].v != 1) flag = 1;
    	}
    	dfs1(1, 0);
    	dfs2(1, 1);
    	for (int i = 1; i <= q; i++) {
    		int u = Q[i].u, v = Q[i].v;
    		int LCA = lca(u, v), d = 0;
    		long long ans = 0;
    		int dis =  depth[u] + depth[v] - 2 * depth[LCA];
    		for (; u != fa[LCA]; u = fa[u], d++) ans += (d | a[u]);
    		d = 0;
    		for (; v != LCA; v = fa[v], d++) ans += ((dis - d) | a[v]);
    		printf("%lld
    ", ans);
    	}
    }
    
  • 相关阅读:
    随笔程序能干啥?
    Net C# 扩展方法
    iOS中控制器的实践和学习(4)简易5图之A4
    简单的程序员
    阅读iPhone.3D.ProgrammingHelloArrow项目
    有感 阅读iPhone.3D.ProgrammingHelloArrow项目
    WebResource.axd
    [转]ASP.NET AJAX clientside framework failed to load
    BinConvertor
    [转]ASP.NET AJAX and Sys.Webforms.PageRequestManagerServerErrorException
  • 原文地址:https://www.cnblogs.com/hzoi-liujiahui/p/13959887.html
Copyright © 2011-2022 走看看