CSP-S模拟赛总结6

T1

题面

你要不要试试图论

时间限制:4秒        内存限制:256M

题目描述

给出三个整数x, y, P,P为素数,可以重复对x执行如下操作:

选择一个整数z ∈ [1, P − 1],花费∣ x − z ∣元钱,使得x = x ∗ z mod P。

最小需要花费多少钱才能使得x = y?

设 ans(i, j) 为 当 x = i, y = j 时的答案,为了减少输出,你需要输出

输入描述

输入两个整数P,t。

输出描述

输出一个整数表示答案。

输入样例1

  1. 2 1

输出样例1

  1. 0

样例说明1

ans矩阵为:

0

答案为: 0∗10=00∗1​0​​=0

输入样例2

  1. 3 233

输出样例2

  1. 233

样例说明2

ans矩阵为:

0,1

0,0

答案为

输入样例3

  1. 5 233

输出样例3

  1. 889807030

样例说明3

ans 矩阵为:

0,1,2,1

0,0,2,0

0,1,0,0

0,1,2,0

答案为:0 233^0 + 1 233^1 + 2 233^2 + 1 233^3 + 0 233^4 + 0 233^5 + 2 233^6 + 0 233^7 +..

数据描述

初次思路

cout<<0;

复盘思路

O(n^3)方法:对于当前数字,推出所有该数字能变成的数字并建图,随后Floyd求最短路并累加即可

AC方法:玄学优化,建图中j范围改为i+-17

code

#include<bits/stdc++.h> 
using namespace std;
int p,t,g[2005][2005],f[2005][2005],mod=998244353;
void fl(){
	for(int o=1;o<p;o++){
        for(int i=1;i<p;i++){
            for(int j=1;j<p;j++){
                g[i][j]=min(g[i][j],g[i][o]+g[o][j]);
            }
        }
    }
}
int main(){
	//freopen("graph.in","r",stdin);
	//freopen("graph.out","w",stdout);
	memset(g,0x3f,sizeof g);
	cin>>p>>t;
	for(int j=1;j<p;j++){
		g[j][j]=0;
	} 
	for(int i=1;i<p;i++){
		for(int j=max(1,i-17);j<min(p,i+17);j++){
			g[i][i*j%p]=abs(i-j);
		} 
	}
	fl();
	for(int i=1;i<p;i++){
		for(int j=1;j<p;j++){
			cout<<g[i][j]<<' ';
		}
		cout<<endl;
	}
	int ans=0,base=1,t;
	for(int i=1;i<p;i++){
		for(int j=1;j<p;j++){
			t=g[i][j]*base%mod;
			ans+=t;
			ans%=mod;
			base*=t;
			base%mod;
		} 
	}
	cout<<ans;
	fclose(stdin);
	fclose(stdout);
	return 0;
}

T2

题面

 数组操作

时间限制:3秒        内存限制:256M

题目描述

输入描述

第一行:输入一个整数n。

第二行:输入n个整数,表示a​i​​ 。

输出描述

输出一行答案。

输入样例

  1. 5
  2. 2 2 2 1 1

输出样例

  1. 40

输入样例

  1. 88
  2. 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3

输出样例

  1. 235381964

数据描述

初次思路

O(n!)复杂度枚举,得20分

复盘思路

区间dp

最小花费

dp[i][j]:区间i,j的最小花费

转移:枚举断点k,dp[i][j]=dp[l][k-1]+dp[k+1][r]+f(k)

最小花费的方案数

cnt[i][j]:区间i,j的最小花费的方案数

转移:枚举断点k,cnt[l][r]=cnt[l][k-1]*cnt[k+1][r]*C[r-l][k-l]

#include<bits/stdc++.h> 
using namespace std;
int n,dp[1005][1005],a[1005],ans,l,r,cnt[1005][1005],fac[1005],infac[1005],sm[1005],pm[1005];
int mod=998244353;
int qp(int m,int n){
    int b = 1;
    while(n>0){
        if (n & 1)
    		b = (b*m)%mod;
        n=n>>1;
         m=(m*m)%mod;
    }
    return b;
}
int C(int a,int b){
    if(a < b) return 0;
    if(b == 0 || a == b) return 1;
    return fac[a] * infac[a - b] % mod * infac[b] % mod;
}
int main(){
	//freopen("array.in","r",stdin);
	//freopen("array.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	fac[0]=1;
	for(int i=1;i<=n;i++){
		fac[i]=fac[i-1]*i%mod;
	}
	infac[n]=qp(fac[n],mod-2);
	for(int i=n-1;i>=0;i--){
		infac[i]=infac[i+1]*(i+1)%mod;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cnt[i][j]=1;
		}
	}
	for(int len=1;len<=n;len++){
		for(int l=1;l+len-1<=n;l++){
			int r=l+len-1;
			pm[l-1]=0;
			for(int i=l;i<=r;i++){
				pm[i]=max(pm[i-1],a[i]);
			}
			sm[r+1]=0;
			for(int i=r;i>=l;i--){
				sm[i]=max(sm[i+1],a[i]);
			}
			dp[l][r]=0x3f3f3f3f;
			for(int i=l;i<=r;i++){
				if(dp[l][r]>dp[l][i-1]+dp[i+1][r]+pm[i-1]+sm[i+1]){
					dp[l][r]=dp[l][i-1]+dp[i+1][r]+pm[i-1]+sm[i+1];
					cnt[l][r]=cnt[l][i-1]*cnt[i+1][r]*C(r-l,i-l);
				}
				else if(dp[l][r]==dp[l][i-1]+dp[i+1][r]+pm[i-1]+sm[i+1]){
					cnt[l][r]+=cnt[l][i-1]*cnt[i+1][r]*C(r-l,i-l);
				}
			}
		}
	}
	cout<<cnt[1][n];
	fclose(stdin);
	fclose(stdout);
	return 0;
}
/*
5
2 2 2 1 1
*/

T3

题面

无穷序列

时间限制:1秒        内存限制:256M

题目描述

输入描述

第一行输入一个整数T,表示测试用例的组数。

每组测试用例输入一行包含两个整数n, c。

其中 n 以二进制形式表示,且 n 不含有前导 0

输出描述

对于每组测试用例输出一行一个整数表示答案。

输入样例

  1. 5
  2. 1001 1
  3. 11111 1
  4. 101010111101 8999
  5. 10100101111010101 799
  6. 10010010 233

输出样例

  1. 45
  2. 496
  3. 2835797
  4. 707482963
  5. 9940

数据描述

初次思路

啊?

复盘思路

啊?

T4

题面

矩阵学说

时间限制:1秒        内存限制:256M

题目描述

给定n行m列的矩阵 ,找出满足以下条件的三元组 (i,j,x) 的数量:

1.1≤i≤n,1≤j≤m,1≤x≤min(n−i+1,m−j+1)
2.矩阵的左上角(i,j) 到右下角)(i+x−1,j+x−1) 恰好含有k个不同的整数。

输入描述

第一行输入三个整数n,m,k。

接下来输入一个 n*m 的矩阵,表示 a​i,j​​

输出描述

输出一行一个整数表示答案。

输入样例

  1. 2 3 4
  2. 1 2 3
  3. 4 5 6

输出样例

  1. 2

样例说明

满足条件的三元组有: (1,1,2),(1,2,2)。

数据描述

初次思路

异或前缀!!!!!!!!!!!!!!!!!!!!!!!!!!!!

不会写!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

很重要!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

等着学!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

复盘思路

二维ST表(看题解)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值