Educational Codeforces Round 89 (Rated for Div. 2)

发布时间 2023-04-18 23:36:16作者: 努力的德华

题目链接

C

核心思路

我们需要保证任意一个点出发都需要回文,所以我们的斜对角先必须的一致,什么意思呢:看下这个样例把。

1 0 1
0 1 0 
1 0 1
比如这种(2,1)和(1,2) 就必须要和(2,3)的和(3,2)的相等。
这个斜对角的点有一个规律就是横纵坐标加起来就是相等的。
比如其中一个加起来是i,那么对称的就是n+m-i;
为了重复,我们需要i<n+m-i.
// Problem: C. Palindromic Paths
// Contest: Codeforces - Educational Codeforces Round 89 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1366/problem/C
// Memory Limit: 256 MB
// Time Limit: 1500 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
#define endl "\n"
#define int long long 
const int INF = 0x3f3f3f3f;
const int N=1e3+10;
int num0[N],num1[N];


void solve()
{
	int n,m;
	cin>>n>>m;
	memset(num0,0,sizeof num0);
	memset(num1,0,sizeof num1);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			int x;
			cin>>x;
			if(x&1)
			num1[i+j-1]++;
			else
			num0[i+j-1]++;
		}
	}
	int ans=0;
	for(int i=1;2*i<n+m;i++)
	{
		ans+=min(num0[i]+num0[n+m-i],num1[i]+num1[n+m-i]);
	}
	cout<<ans<<endl;
	
	
}



signed main()
{
int t;
cin>>t;
while(t--)
{
	solve();
}
}

D

核心思路

首先我们可以从因式入手吧,\(a=p_1^{k_1}* p_2^{k_2}*....*p_n^{k_n}\).然后任意取一个公因子\(p_x\).所以\(a=p_x*d^{k}\).其中\(d^k\)就是提取公因式后面一坨。然后就是证明\(P_x+d^k和a互质\)

首先就是\(p_x+d^k和p_x互质\)。这个还是很显然的吧,因为\(d^k 肯定是和p_x互质的。所以这是不可以整除的。\)

同理也可以得和\(p_x+d_k 和d_k是互质的\)

所以说明这个是成立的。

然后这里有一个很重要的的点就是我们可以再线性筛里面预处理出来每一个数的某一个公因数。

E

核心思路

这个题目的解题关键在于b数组单调递增的,所以我们可以往把a的前缀min数组求出来或者是把a的后缀min数组求出来。然后求出来可以干嘛呢

sufmin(a): 10 10 20 20 30 30
b: 10 20 30
然后就是发现其中的性质:然后我们发现对于10这个答案来说贡献其实是20这个元素的数目,因为把20分入10的元素的组是不会影响我们的最小值的。
所以得出来这个结论从前往后递推就完事了。但是注意要从b的第二个元素开始,因为第一个元素的前面没有元素。而这又是一个后对前产生贡献的过程。
可能还是对为什么可以全都划过去不理解,直接模拟下第一个样例。

仔细回顾,发现这题其实也还好吧。主要是需要想到后缀最小值。然后把他转换为贡献题求解就好了。