Codeforces#816 (Div. 2)

A.Crossmarket

一个人得全走,另一个人可以用一步横跨一行或者一列,即:

answer : (n−1)+(m−1)+1+(min(n,m)−1)=min(n,m)+n+m−2.

特判:(n,m)=(1,1) answer is 0

#include
#define int long long
using namespace std;
const int N =3e5+10,mod=998244353;

signed main()
{
    int T;
    cin>>T;
    while(T--)
    {
    	int m,n;
    	
    	cin>>n>>m;
    	if(m==n&&m==1)
    	{
    		cout<<0<

B.1715B - Beautiful Array

the existence of the answer: k⋅b ≤ s ≤ k⋅b+(k−1)⋅n

意思就是s起码要为k*b,不然漂亮值凑不到b。上限是不能超过k⋅b+(k−1)⋅n,就是其余位是k-1,最大的那一位是k*b+k-1(减一是保证除k后向下取整的结果不是k+1,是k)

然后就输出就行,符合条件即可,顺序不重要

#include
#define int long long
using namespace std;
const int N =3e5+10,mod=998244353;

signed main()
{
    int t;
    cin>>t;
    while(t--)
    {
    	int n,k,b,s;
    	cin>>n>>k>>b>>s;
    	if(s=k-1)
				cout<0)
				cout<

C.1715C - Monoblock

先提一下题解里的式子:ans += (a[i] != a[i + 1]) * (n - (i + 1) + 1) * i;

//我一下看不透,但大概意思应该差不多,我的思路是这样的:

考虑每一位数字的贡献就行,对于包含这个数字的区间,与前一个数字重复、不重复的两种情况有不同的贡献;

如果与前一个数字不同,那贡献就是 i*(n-i+1);

否则贡献就是n-i+1(和另一种情况的差距就是不包含上一个数字的区间);

ans初始化为n,默认第一个数字对包含它的n个区间都有1的贡献。

然后在m次改数据的时候,先减去原本的数对左右的影响,改变后再加上对左右的影响即可。

写一组数据看看:1 2 2 4 5

Codeforces#816 (Div. 2)_第1张图片

#include
#define int long long
using namespace std;
const int N =3e5+10,mod=998244353;

signed main()
{
    int n, m;
    cin >> n >> m;
    vector a(n + 2, 0);
    for (int i = 1; i <= n; ++i) 
	{
        cin >> a[i];
    }
    int ans = n;
    for(int i=2;i<=n;i++)
	{
		if(a[i]!=a[i-1])
			ans+=i*(n-i+1);
		else
			ans+=n-i+1;
	} 
	//cout<<"ans="<>index>>x;
		//先减去原来的 
		if(a[index]!=a[index-1])
			ans-=index*(n-index+1);
		else
			ans-=n-index+1;
		if(a[index+1]!=a[index])
			ans-=(index+1)*(n-(index+1)+1);
		else
			ans-=n-(index+1)+1;
		//改变后加上新的
		a[index]=x;
		if(a[index]!=a[index-1])
			ans+=index*(n-index+1);
		else
			ans+=n-index+1;
		if(a[index+1]!=a[index])
			ans+=(index+1)*(n-(index+1)+1);
		else
			ans+=n-(index+1)+1;
		cout<

你可能感兴趣的:(算法,c++)