• JZOJ 2022.02.26【提高A组】模拟


    比赛总结

    考场 \(T1,T2\) 思想切了
    然而。。。

    \(\text{T1}\) 飞行棋

    当然要 \(dp\),然而发现后六格有后效性
    姑且设 \(f_i\) 表示从第 \(i\) 格到终点的期望次数
    那么如果成功特殊处理后六格,就可以倒着 \(dp\)
    答案就是 \(f_0+\frac{1}{p_6}\)
    考虑起飞的期望,有 \(x = p_6+(1-p_6)(x+1)\)
    解得 \(x=\frac{1}{p_6}\)
    那问题就落在处理六格格子上
    其实也可以列出五元一次方程组,高斯消元即可
    注意:判无解!
    考场因为这个只剩 \(50\) (多测竟然能有 \(50pts\) !)

    \(\text{Code}\)

    #include <cstdio>
    #include <iostream>
    #define RE register
    #define IN inline
    using namespace std;
    
    double p[9], f[59], a[7][7];
    
    IN void GaoSi()
    {
    	for(RE int i = 1; i <= 5; i++)
    		for(RE int j = 1; j <= 6; j++) a[i][j] = 0;
    	for(RE int i = 1; i <= 5; i++)
    	{
    		for(RE int j = 1; j <= 6; j++)
    		{
    			int k = i + j;
    			if (k == 6) continue;
    			if (k > 6) k = 12 - k;
    			a[i][k] += p[j];
    		}
    		a[i][i] -= 1, a[i][6] = -1;
    	}
    	int n = 5;
    	for(RE int i = 1; i <= n; i++)
    	{
    		for(RE int j = i; j <= n; j++)
    		if (a[i][j] != 0)
    		{
    			for(RE int k = 1; k <= n + 1; k++) swap(a[i][k], a[j][k]);
    			break;
    		}
    		for(RE int j = i + 1; j <= n + 1; j++) a[i][j] /= a[i][i];
    		a[i][i] = 1.0;
    		for(RE int j = 1; j <= n; j++)
    		if (i ^ j)
    		{
    			double p = a[j][i];
    			for(RE int k = 1; k <= n + 1; k++) a[j][k] -= a[i][k] * p;
    		}
    	}
    }
    
    int main()
    {
    	int T; scanf("%d", &T);
    	for(; T; --T)
    	{
    		for(RE int i = 1; i <= 6; i++) scanf("%lf", &p[i]);
    		if (p[6] == 0 || p[6] + p[3] == 1){printf("T_T\n"); continue;}
    		GaoSi();
    		for(RE int i = 0; i <= 56; i++) f[i] = 0;
    		for(RE int i = 1; i <= 5; i++) f[50 + i] = a[i][6];
    		for(RE int i = 50; i >= 0; i--)
    			for(RE int j = 1; j <= 6; j++)
    			{
    				int k = i + j;
    				if (k == 18) k = 30;
    				if (k % 4 == 2 && k <= 46) k += 4;
    				if (k == 18) k = 30;
    				f[i] += p[j] * (f[k] + 1);
    			}
    		printf("%.8lf\n", f[0] + 1 / p[6]);
    	}
    }
    

    \(\text{T2}\) 大山王国的科举考试

    看到数据范围就知道要发现一些东西
    考虑 \(p\) 很小的时候,可以预处理模每个 \(p\) 下的答案
    \(p\) 很大时,可以枚举 \(p\) 的倍数 \(K\),找数值范围在 \([K,K+p-1]\) 中的最大值,主席树即可
    注意到时间和空间限制,可以平衡规划一下
    又注意到数据范围有一档 \([34,1000]\) 不妨就取这个
    然而又注意到题目范围有 \(p >= 2\)
    于是可以节省空间把若干棵线段树的第 \(0,1\) 棵用上
    于是光荣 \(45pts\) ?!!!
    艹,数据有 \(p_i = 1\) !!!!
    感谢!!!

    \(\text{Code}\)

    #include <cstdio>
    #include <iostream>
    #define RE register
    #define IN inline
    using namespace std;
    
    const int N = 1e6 + 5;
    int n, q, dch = 32, a[N], rt[N];
    
    IN void read(int &x)
    {
    	x = 0; char ch = getchar();
    	for(; !isdigit(ch); ch = getchar());
    	for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar());
    }
    
    struct Segment{
    	short tr[N * 4];
    	void build(int p, int l, int r, int k)
    	{
    		if (l == r) return tr[p] = a[l] % k, void();
    		int mid = l + r >> 1;
    		build(p << 1, l, mid, k), build(p << 1 | 1, mid + 1, r, k);
    		tr[p] = max(tr[p << 1], tr[p << 1 | 1]);
    	}
    	int Query(int p, int l, int r, int x, int y)
    	{
    		if (x <= l && r <= y) return tr[p];
    		int mid = l + r >> 1, res = 0;
    		if (x <= mid) res = Query(p << 1, l, mid, x, y);
    		if (y > mid) res = max(res, Query(p << 1 | 1, mid + 1, r, x, y));
    		return res;
    	}
    }T[31];
    
    struct Chairman{
    	int sum[N * 13], ls[N * 13], rs[N * 13], size;
    	void insert(int &p, int pre, int l, int r, int x)
    	{
    		sum[p = ++size] = sum[pre] + 1, ls[p] = ls[pre], rs[p] = rs[pre];
    		if (l == r) return;
    		int mid = l + r >> 1;
    		if (x <= mid) insert(ls[p], ls[pre], l, mid, x);
    		else insert(rs[p], rs[pre], mid + 1, r, x);
    	}
    	int Query(int p, int pre, int l, int r, int x)
    	{
    		if (sum[p] - sum[pre] == 0) return -1;
    		if (l == r) return l;
    		int mid = l + r >> 1, res = -1;
    		if (x > mid && sum[rs[p]] - sum[rs[pre]]) res = Query(rs[p], rs[pre], mid + 1, r, x);
    		if (res == -1 && sum[ls[p]] - sum[ls[pre]]) res = Query(ls[p], ls[pre], l, mid, x);
    		return res;
    	}
    }C;
    
    int main()
    {
    	read(n), read(q);
    	for(RE int i = 1; i <= n; i++) read(a[i]), C.insert(rt[i], rt[i - 1], 0, 1000, a[i]);
    	for(RE int j = 2; j < dch; j++) T[j - 2].build(1, 1, n, j);
    	for(RE int p, l, r, ans; q; --q)
    	{
    		read(l), read(r), read(p), ++l, ++r, ans = 0;
    		if (p < 2){printf("0\n"); continue;}
    		if (p < dch) printf("%d\n", T[p - 2].Query(1, 1, n, l, r));
    		else{
    			for(RE int j = 0; j <= 1000; j += p)
    				ans = max(ans, C.Query(rt[r], rt[l - 1], 0, 1000, min(j + p - 1, 1000)) - j);
    			printf("%d\n", ans);
    		}
    	}
    }
    
  • 相关阅读:
    查看gpu和cpu使用情况 linux
    Oracle通过数据文件进行 数据恢复
    LeetCodeJava题解 283. Move Zeroes
    LeetCodeJava题解 844. Backspace String Compare
    LeetCodeJava题解 27. Remove Element
    LeetCodeJava题解 367. Valid Perfect Square
    LeetCodeJava题解 26. Remove Duplicates from Sorted Array
    EasyExcel实现合并一列的多行数据
    编辑qml的工具及插件
    qml学习(Qt Quick)
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15939423.html
Copyright © 2020-2023  润新知