• 2020-11-25 考试总结


    考得很炸,不是挂分太多了,主要是自己没想到,但是似乎不挂分排名还是比较好看的???

    T1

    水得一批,懒得讲。

    T2 CF575A Fibonotci

    题目传送门

    思路

    胡确实是很好胡,但是具体实现上面需要一定的技巧。于是借鉴了Rainybunny的Code

    不难看出,如果没有修改操作,那么肯定是每 (n) 个数为一个循环段,每一个循环段某一个数与开头两个数相对关系确定。这个玩意就可以用矩阵进行优化。

    考虑有修改,不难看出就是改了一个矩阵,具体来说可以直接拆开考虑。不过麻烦的地方就是如何考虑相邻的两处修改,其实你可以记录一下当前已经考虑了前面的多少位,通过判断当前位与修改点的关系判断这个矩阵是否被考虑到即可。具体可以见代码。

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define int long long
    #define MAXN 50005
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int n,m,K,lg,mod,s[MAXN];
    int mul (int a,int b){return 1ll * a * b % mod;}
    int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
    int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
    
    struct Matrix{
    	int a,b,c,d;
    	Matrix(){}
    	Matrix (int _a,int _b,int _c,int _d){a = _a,b = _b,c = _c,d = _d;}
    	Matrix operator * (const Matrix &p)const{return Matrix (add (mul (a,p.a),mul (b,p.c)),add (mul (a,p.b),mul (b,p.d)),add (mul (c,p.a),mul (d,p.c)),add (mul (c,p.b),mul (d,p.d)));}
    }st[MAXN][65],tmp,ans;
    
    void init (){
    	for (Int i = 0;i < n;++ i) st[i][0] = Matrix (0,1,s[i],s[(i + 1) % n]);
    	for (Int j = 1;(1ll << j) <= K;lg = j ++)
    		for (Int i = 0;i < n;++ i)
    			st[i][j] = st[(i + (1ll << j - 1)) % n][j - 1] * st[i][j - 1];
    }
    
    void getit (int& cur,int goal){
    	for (Int i = lg;~i;-- i)
    		if (cur + (1ll << i) < goal)
    			ans = st[cur % n][i] * ans,cur += (1ll << i);
    }
    
    #define PII pair<int,int>
    PII sk[MAXN];
    
    signed main(){
    	read (K,mod,n);
    	if (mod == 1) return puts ("0"),0;
    	for (Int i = 0;i < n;++ i) read (s[i]);
    	init ();
    	read (m);for (Int i = 1;i <= m;++ i){
    		read (sk[i].first,sk[i].second);
    		if (sk[i].first >= K) -- i,-- m; 
    	}
    	sort (sk + 1,sk + m + 1),ans.c = 1;int cur = 0;
    	for (Int i = 1;i <= m;++ i){
    		getit (cur,sk[i].first);
    		if (cur < sk[i].first) tmp = Matrix (0,1,s[cur % n],sk[i].second),ans = tmp * ans,++ cur;
    		if (i != m && sk[i + 1].first == sk[i].first + 1) tmp = Matrix (0,1,sk[i].second,sk[i + 1].second);
    		else tmp = Matrix (0,1,sk[i].second,s[(cur + 1) % n]);
    		ans = tmp * ans,++ cur;
    	}
    	getit (cur,K);
    	write (cur < K ? ans.c : ans.a),putchar ('
    ');
    	return 0;
    }
    

    T3 CF480E Parking Lot

    题目传送门

    思路

    原题做不出系列。。。

    首先考虑 50 pts做法(我才不会告诉你我写的 (nmklog n) 结果只有 10 pts),我们不难看出可以设 (f_{i,j}) 表示以 ((i,j)) 为底部的最大正方形边长,可以得到转移式:

    [f_{i,j}=min(f_{i-1,j},f_{i,j-1},f_{i-1,j-1})+1 ]

    考虑 100 pts,不难看出正着做不好做,于是我们可以倒着做。于是要求的就是删除一个位置,包含这个位置的最大正方形边长。

    这个比较好搞,我们可以用并查集维护一下空位,然后用单调性就可以做到 (Theta(nm))。(假设并查集是线性的。)

    ( exttt{Code}) (一年前的代码了)

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e3 + 10;
    int n,m,k;
    int Ans;
    int dp[maxn][maxn];
    int l1[maxn];
    int r1[maxn];
    int qx[maxn];
    int qy[maxn];
    int ans[maxn];
    char Map[maxn][maxn];
    
    struct node
    {
    	int fa[maxn];
    	int findSet (int x)
    	{
    		if (x == fa[x]) return x;
    		else return fa[x] = findSet (fa[x]);
    	}
    }l[maxn],r[maxn];
    
    void Delete(int x,int y)
    {
    	l[x].fa[y] = l[x].findSet(y - 1);
    	r[x].fa[y] = r[x].findSet(y + 1);
    }
    
    int main()
    {
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i = 1; i <= n; i++)
    		scanf("%s", Map[i]+1);
    	for(int i = 1; i <= k; i++)
    	{
    		scanf("%d%d",&qx[i],&qy[i]);
    		Map[qx[i]][qy[i]] = 'X';
    	}
    	for(int i = 1; i <= n; i++)
    	{
    		for(int j = 1; j <= m+1; j++)
    		{
    			l[i].fa[j] = j;
    			r[i].fa[j] = j;
    		}
    	}
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= m; j++)
    			if(Map[i][j] == '.')
    				Delete(i, j);
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= m; j++)
    			if(Map[i][j] == '.')
    			{
    				dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j],dp[i][j-1]))+1;
    				Ans = max (Ans,dp[i][j]);
    			}
    	for (int j = k;j >= 1;-- j)
    	{
    		ans[j] = Ans;
    		Delete (qx[j],qy[j]);
    		for(int i = 1; i <= n; i++)
    		{
    			l1[i] = qy[j] - l[i].findSet(qy[j]);
    			r1[i] = r[i].findSet(qy[j]) - qy[j];
    		}
    		for(int i = qx[j] + 1; i <= n; i++)
    		{
    			l1[i] = min(l1[i], l1[i - 1]);
    			r1[i] = min(r1[i], r1[i - 1]);
    		}
    		for(int i = qx[j] - 1; i; i--)
    		{
    			l1[i] = min(l1[i], l1[i + 1]);
    			r1[i] = min(r1[i], r1[i + 1]);
    		}
    		for(int i = 1; i <= qx[j]; i++)
    			while(min(r1[i], r1[i + Ans]) + min(l1[i], l1[i + Ans]) - 1 > Ans)
    				Ans++;
    	}
    	for(int i = 1; i <= k; i ++)
    		printf("%d
    ",ans[i]);
    	return 0;
    }
    

    T4 ant

    题目传送门

    思路

    不难看出 (n^6) 的高斯消元优化。

    不难看出如果我们确定边界上的期望值,那我们就可以确定每一个点的 dp 值。于是拿这个解方程就可以做到 (Theta(n^3)) 了。

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define hash screwyourwholefamily
    #define double long double
    #define Int register int
    #define get whysoserious
    #define MAXN 205
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int n,m,x,y;
    int hash (int x,int y){return !x ? y : m - 1 + x;}
    
    struct node{
    	double a[MAXN << 1];
    }get[MAXN][MAXN];
    
    double mat[MAXN][MAXN],f[MAXN];
    
    signed main(){
    //	freopen ("ant.in","r",stdin);
    //	freopen ("ant.out","w",stdout);
    	read (n,m,x,y);
    	for (Int i = 0;i < m;++ i) get[0][i].a[hash (0,i)] = 1;
    	for (Int i = 0;i < n;++ i) get[i][0].a[hash (i,0)] = 1;
    	for (Int i = 1;i < n;++ i)
    		for (Int j = 1;j < m;++ j){
    			for (Int k = 0;k <= n + m - 1;++ k)
    				get[i][j].a[k] = 0.5 * (get[i - 1][j].a[k] + get[i][j - 1].a[k]);
    			get[i][j].a[n + m - 1] ++;
    		}
    	int up = n + m - 1;
    	mat[0][0] = 1;
    	for (Int i = 1;i < m;++ i){
    		mat[hash (0,i)][hash (0,i)] = mat[hash (0,i)][up] = 2;
    		for (Int j = 0;j <= up;++ j) if (j != up) mat[hash (0,i)][j] -= get[0][i - 1].a[j];else mat[hash (0,i)][j] += get[0][i - 1].a[j];
    		for (Int j = 0;j <= up;++ j) if (j != up) mat[hash (0,i)][j] -= get[n - 1][i].a[j];else mat[hash (0,i)][j] += get[n - 1][i].a[j];
    	}
    	for (Int i = 1;i < n;++ i){
    		mat[hash (i,0)][hash (i,0)] = mat[hash (i,0)][up] = 2;
    		for (Int j = 0;j <= up;++ j) if (j != up) mat[hash (i,0)][j] -= get[i - 1][0].a[j];else mat[hash (i,0)][j] += get[i - 1][0].a[j];
    		for (Int j = 0;j <= up;++ j) if (j != up) mat[hash (i,0)][j] -= get[i][m - 1].a[j];else mat[hash (i,0)][j] += get[i][m - 1].a[j];
    	}	
    	for (Int i = 0;i < up;++ i){
    		int pos = i;
    		for (Int j = i + 1;j < up;++ j) if (abs (mat[j][i]) > abs (mat[pos][i])) pos = j;
    		if (abs (mat[pos][i]) < 1e-9) continue;
    		if (pos ^ i) swap (mat[pos],mat[i]);
    		for (Int j = i + 1;j < up;++ j){
    			double d = mat[j][i] / mat[i][i];
    			for (Int k = i;k <= up;++ k) mat[j][k] -= mat[i][k] * d; 
    		} 
    	}
    	for (Int i = up - 1;~i;-- i){
    		for (Int j = i + 1;j < up;++ j)
    			mat[i][up] -= mat[i][j] * f[j];
    		f[i] = mat[i][up] / mat[i][i];
    	}
    	double ans = get[x][y].a[up];
    	for (Int i = 0;i < up;++ i) ans += get[x][y].a[i] * f[i];
    	printf ("%.15Lf
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    选择排序与冒泡排序
    判断是否为偶数
    mysql基础之mysql双主(主主)架构
    mysql基础之mysql主从架构半同步复制
    mysql基础之mysql主从架构
    mysql基础之数据库备份和恢复实操
    mysql基础之数据库备份和恢复的基础知识
    mysql基础之日志管理(查询日志、慢查询日志、错误日志、二进制日志、中继日志、事务日志)
    mysql基础之查询缓存、存储引擎
    mysql基础之数据库变量(参数)管理
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/14038871.html
Copyright © 2020-2023  润新知