zoukankan      html  css  js  c++  java
  • 「2019纪中集训Day2」解题报告

    T1、Attack

    bzoj2674

    这道题时间给的比较多 (可能是以前评测机比较弱)(O(nm)) 就可以过。

    (Sol) 给了分块加划分树的做法,不是很会,但是这道题可以用很多数据结构来做;
    我写了整体二分+树套树 (还没调出来),整体二分+ (cdq) 也行,代码应该是最短的。

    只给出 (O(nm)) 的代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    int in() {
    	int x = 0; char c = getchar(); bool f = 0;
    	while (c < '0' || c > '9')
    		f |= c == '-', c = getchar();
    	while (c >= '0' && c <= '9')
    		x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    	return f ? -x : x;
    }
    template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
    template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }
    
    const int N = 6e4 + 5;
    
    struct node {
    	int x, y, z;
    } a[N];
    
    int n, m, id[N], rnk[N];
    
    inline bool cmp(const int &i, const int &j) {
    	return a[i].z < a[j].z;
    }
    
    char s[11];
    
    int main() {
    //	freopen("in", "r", stdin);
    	n = in(), m = in();
    	for (int i = 1; i <= n; ++i)
    		a[i] = (node){in(), in(), in()}, id[i] = i;
    	std::sort(id + 1, id + 1 + n, cmp);
    	for (int i = 1; i <= n; ++i)
    		rnk[id[i]] = i;
    	while (m--) {
    		scanf(" %s", s);
    		if (s[0] == 'S') {
    			int u = in() + 1, v = in() + 1;
    			std::swap(a[u].z, a[v].z);
    			std::swap(id[rnk[u]], id[rnk[v]]);
    			std::swap(rnk[u], rnk[v]);
    		} else {
    			int x = in(), y = in(), p = in(), s = in(), k = in();
    			if (!k) {
    				puts("It doesn't exist.");
    				continue;
    			}
    			if (x > p)
    				std::swap(x, p);
    			if (y > s)
    				std::swap(y, s);
    			for (int i = 1; i <= n; ++i) {
    				if (a[id[i]].x >= x && a[id[i]].y >= y && a[id[i]].x <= p && a[id[i]].y <= s)
    					--k;
    				if (!k) {
    					printf("%d
    ", a[id[i]].z);
    					break;
    				}
    			}
    			if (k)
    				puts("It doesn't exist.");
    		}
    	}
    	return 0;
    }
    

    T2、Contra

    bzoj2676

    (Sol)
    (f[i + 1][min(j + 1,Q)][min(k + 1, R)] += p imes f[i][j][k]) (第 (i +1) 轮通过);
    (f[i + 1][j - 1][0] += (1 - p) imes f[i][j][k], (j > 1)) (第 (i + 1) 轮不通过);
    因为期望的线性性,可以单独计算每一轮游戏的贡献, (ans = sum {f[i][j][k] imes p imes min(k + 1, R)}),其中 (f[i][j][k]) 为合法状态。

    因为合法状态数最多不超过 (frac{Q * (Q - 1)}{2} + R + 1),所以可以矩阵优化。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    typedef double db;
    int in() {
    	int x = 0; char c = getchar(); bool f = 0;
    	while (c < '0' || c > '9')
    		f |= c == '-', c = getchar();
    	while (c >= '0' && c <= '9')
    		x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    	return f ? -x : x;
    }
    template<typename T>inline void chk_min(T &_, T __) { _ = _ < __ ? _ : __; }
    template<typename T>inline void chk_max(T &_, T __) { _ = _ > __ ? _ : __; }
    
    const int M = 45;
    const db eps = 4e-8;
    
    int n, r, q, s, nn;
    
    struct matrix {
    	db a[M][M];
    	matrix(db t = 0) {
    		memset(a, 0, sizeof(a));
    		if (t > 0)
    			for (int i = 1; i <= nn; ++i)
    				a[i][i] = t;
    	}
    	inline db* operator [] (int x) {
    		return a[x];
    	}
    	inline matrix operator * (matrix &b) const {
    		matrix ret;
    		for (int k = 1; k <= nn; ++k)
    			for (int i = 1; i <= nn; ++i)
    				for (int j = 1; j <= nn; ++j)
    					ret[i][j] += a[i][k] * b[k][j];
    		return ret;
    	}
    } ;
    
    matrix qpow(matrix base, int b) {
    	matrix ret(1);
    	for (; b; b >>= 1, base = base * base)
    		if (b & 1)
    			ret = ret * base;
    	return ret;
    }
    
    int state[7][21], cnt;
    db calc(db p) {
    	matrix a(0), trans(0);
    	a[1][state[q][1]] = p, a[1][state[q - 1][0]] = 1 - p, a[1][nn] = p * std::min(1, r);
    	trans[nn][nn] = 1;
    	for (int j = 1; j <= q; ++j) {
    		for (int k = 0; k <= r; ++k) {
    			if (j != q && k >= j)
    				continue;
    			int x = std::min(q, j + 1), y = std::min(r, k + 1);
    			trans[state[j][k]][state[x][y]] = p;
    			trans[state[j][k]][state[j - 1][0]] = 1 - p;
    			trans[state[j][k]][nn] = p * std::min(r, k + 1);
    //			printf("%lf
    ", trans[state[j][k]][nn]);
    		}
    	}
    	trans = qpow(trans, n - 1);
    	a = a * trans;
    	return a[1][nn];
    }
    
    int main() {
    //	freopen("in", "r", stdin);
    	n = in(), r = in(), q = in(), s = in();
    	for (int i = 1; i <= q; ++i)
    		for (int j = 0; j <= r; ++j)
    			if ((i == q) || (j < i))
    				state[i][j] = ++nn;
    	++nn;
    	if (calc(1) - s < eps) {
    		puts("Impossible.");
    		return 0;
    	}
    	db l = 0, r = 1, mid;
    	while (r - l > eps) {
    		mid = (l + r) / 2;
    		if (calc(mid) > s)
    			r = mid;
    		else
    			l = mid + eps;
    	}
    	printf("%lf
    ", l);
    	return 0;
    }
    

    T3、Bomb

    bzoj2675

    最大值分类讨论,最小值分治即可 (也可以选择随机化分治)

  • 相关阅读:
    变量的分类
    诫子书
    变量variable
    标识符Identifier
    保留字reserved word
    关键字keyword
    编译运行代码的指令
    创建如下的类,使得运行的话可以输出
    常用的几个命令行操作都有哪些?
    idea快捷键整合-无鼠标操作idea
  • 原文地址:https://www.cnblogs.com/15owzLy1-yiylcy/p/11295452.html
Copyright © 2011-2022 走看看