Codeforces Round 970 (Div. 3)

A. Sakurako's Exam
分类讨论即可,当a为奇数,无法消去1,或者a==0且b为奇数时,无法消去2

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef  pair<int,int> pii;

void solve()
{
	int a,b;
	int flag=1; 
	cin>>a>>b;
	if(a&1 ) flag=0;
	else if(a==0 and b&1) flag=0;
	
	if(flag) cout<<"Yes";
	else cout<<"No";
	cout<<endl;
	
}

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

B. Square or Not
这题被hack了,假如是64,每行16个,虽然是美丽矩阵,但不是正方形,所以要保证第一个0的下标-1的平方为n,这样才可以确保是个正方形。

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef  pair<int,int> pii;

void solve()
{
	int flag=1;
	int n; cin>>n;
	if(sqrt(n)!=(int)sqrt(n)) flag=0;
	string s;
	cin>>s;
	
	int p=s.find('0');
	if((p-1)*(p-1)!=n&&n!=4) flag=0;
	if(flag) cout<<"Yes";
	else cout<<"No";
	cout<<endl;
	
	
}

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

C. Longest Good Array
可以暴力枚举,也可以二分答案

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef  pair<int,int> pii;

void solve()
{
	int a,b;
	cin>>a>>b;
	int l=2,r=1e9;
	b-=a;
	int mid;
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(mid*(mid-1)/2<=b) l=mid+1;
		else r=mid-1;
	}
	cout<<l-1<<endl;
}

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

D. Sakurako's Hobby
这题其实是找置换环,置换环内的点可以相互到达,然后用并查集维护黑块的个数

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int f[N],p[N];
string s;
int size0[N],size1[N];//size0为从i出发经历过0的数量

//----------并查集找环---------
int find(int x)
{
    return f[x]==x?f[x]:f[x]=find(f[x]);
}

void merge(int x,int y)
{
    x=find(x),y=find(y);
    if(x==y) return;
    f[y]=x;
    size0[x]+=size0[y];
}

//-----------------------------

void solve()
{
    int n; 
    cin>>n;
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=n;i++) cin>>p[i];
    cin>>s;
    s=" "+s;
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='0') size0[i]=1,size1[i]=0;
        else size1[i]=1,size0[i]=0;
    }
    
    for(int i=1;i<=n;i++) merge(i,p[i]);//合并祖先
    for(int i=1;i<=n;i++)
    {
        int x=find(i);
        cout<<size0[x]<<" ";
    }
    
    cout<<endl;
}

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

E. Alternating String
分为奇偶来讨论
如果是偶数,我们只需要统计奇数位上出现次数最多的字母和偶数位上出现次数最多的字母,然后用n减掉这两个数就是最小操作次数了
如果是奇数,肯定要选择一个位置删掉,然后再按偶数来进行操作,枚举位置来删除时,这个位置后面的每个字母的奇偶就会变化,比如abcab,奇数位上a(1)偶数位上a(4),删掉c以后呢,a(3),所以对应字母的奇数位数量要加到偶数位的数量上,偶数位上的同理,然后比较再取最大值即可

#include <bits/stdc++.h>
using namespace std;

void solve()
{
	int n;
	cin>>n;
	string s;
	cin>>s;
    int ans=0;
	if(n&1)
	{
		vector pre(2,vector<int>(30));//第0行为偶数数组 第1行为奇数数组 
		auto suf=pre;
		//pre为当前位置前面奇偶位数上字符的数量
		//suf为后面 
		for(int i=0;i<n;i++) suf[i&1][s[i]-'a']++;//统计奇数和偶数位上各字母的数量 
		for(int i=0;i<n;i++)
		{
			suf[i&1][s[i]-'a']--;//枚举删除的位置,删除完这个位置前 
			int res=0;
			for(int k=0;k<2;k++){
			//每个字母在奇数位和偶数位上都会有计数
			//所以两次循环删除这位数以后,奇偶会互换
			//所以把对应的字母的pre[奇][字母]+suf[偶][字母] 反之同理 
			int mx=0;
			for(int j=0;j<26;j++)
			{
				int t=pre[k][j]+suf[k^1][j];
				if(t>mx) mx=t;
			}
			res+=mx;
			}
			//从左往右遍历,所以pre是慢慢增加的 
			pre[i&1][s[i]-'a']++;
			ans=max(ans,res); 
		}
		ans=n-ans;
	}else{
	//偶数 直接找奇偶位置上的最大数量的字母 
		vector res(2,vector<int>(30) );
		for(int i=0;i<n;i++) res[i&1][s[i]-'a']++;
		for(int i=0;i<2;i++)
		{
			auto mx=*max_element(res[i].begin(),res[i].end());
			ans+=mx;
		}
		ans=n-ans;
		
	}
	cout<<ans<<endl;
}



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

F. Sakurako's Box
题意其实非常的简单只需要求出这个等式即可,就是考察逆元的知识点
\(a_1*(a_2+a_3+a_4)\quad+\quad a_2*(a_3+a_4)+a_3*a_4\)
这一部分可以用类似前缀和来优化sum为所有值的和 每一步(sum-ai)*ai即可

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mod 1000000007

int n,sum;
int ve[200005];


int qpow(int a,int n)
{
    int res=1;
    while(n){
    if(n&1) res=res*a%mod;
    n>>=1;
    a=a*a%mod;
    }
    return res;
}



void solve()
{
    cin>>n;
    sum=0;
    for(int i=0;i<n;i++){
        cin>>ve[i];
        sum+=ve[i];
    }
    
    int fz=0;
    for(int i=0;i<n;i++)
    {
        sum-=ve[i];//这里就是优化的部分,稍微想一下就明白了
        fz+=sum%mod*ve[i]%mod;
    }
    int fm=n*(n-1)/2%mod;//这也要记得mod
    int ans;
    ans=fz%mod  *   qpow(fm,mod-2)%mod;// *左边为分子    右边为分母 1/x=qpow(x,mod-2)
    cout<<ans<<endl;
    
 
 
}

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

posted on 2024-09-07 23:05  swj2529411658  阅读(85)  评论(0)    收藏  举报

导航