2022.3.19 训练

A :Subsequence Hate CodeForces - 1363B

题目链接
题意:可以把0改成1或者把1改成0 让子序列不存在010或者101 最少改变几次?
题解:最后的形态一定是0000…11111 11111…0000 11111…1111 0000…0000
记录01数量前缀和以及01一共的数量 On枚举即可

#include 
#include 
#include 
using namespace std;
const int maxm=1e5+100;
int a[maxm],b[maxm];
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		string s1;
		cin>>s1;
		int tot1,tot2;
		tot1=tot2=0;
		for(int i=0;i<s1.size();i++)
		{
			if(i==0) a[0]=b[0]=0;
			else a[i]=a[i-1],b[i]=b[i-1];
			if(s1[i]=='0') a[i]++,tot1++;
			else b[i]++,tot2++;
		}
		int ans=0x7fffffff;
		for(int i=0;i<s1.size();i++)
		{
			ans=min(ans,a[i]+tot2-b[i]);
			ans=min(ans,b[i]+tot1-a[i]);
		}
		ans=min(ans,min(tot1,tot2));
		cout<<ans<<endl;
	}
	return 0;
}

B:Unmerge CodeForces - 1382D

题目链接
题意:关于 a b两个序列定义操作 每次取出两个队首较小的权值放到新的序列里
每次给你一个(1,2*n)的排列 问存不存在两个大小为n的排列通过merge操作得到给你的排列
题解:对于给定的排列 如果一个数后面存在x个比这个数字小的数 那么这x+1个数字一定在一个排列里
否则后面的数字不可能出现在这个数字后面 比如 3 1 2 这个三个数字一定是在a或者b同一个排列里的。
我们把这2 * n个数字的排列通过这种方式拆成若干个长度的子串 最后看看可不可以拼出两个长度为n的排列来就行了 01背包实现

#include 
#include 
#include 
#include 
using namespace std;
const int maxm=1e5+100;
int dp[maxm],n,m;
int val[maxm];
vector <int> a;
int main()
{
	cin>>m;
	while(m--)
	{
		memset(dp,0,sizeof(dp));
		a.clear();
		cin>>n;
		for(int i=1;i<=2*n;i++)
			cin>>val[i];
		for(int i=1;i<=2*n;)
		{
			int now=i+1;
			while(1)
			{
				if(now>n*2) break;
				if(val[now]>val[i]) break;
				now++;
 			}
 			now--;
 			a.push_back(now-i+1);
 			i=now+1;
		}
		dp[0]=1;
		for(int i=0;i<a.size();i++)
			for(int j=n;j>=a[i];j--)
				dp[j]=max(dp[j],dp[j-a[i]]);
		if(dp[n]) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

C:Primes and Multiplication CodeForces - 1228C

题目链接
题意:Prime(x)是x质因数集合 G(x,y)是指y^k这个值最大且这个值是x的因数 F(x,y)=G(y,p) 其中p是prime(x)里面的元素。
求解 F(x,1) * F(x,2)*…*F(x,n)
题解:
G(x,y)=y^k如果y是一个质数 显然k是这个质数在x的质因数分解里面出现的次数
F(x,y)=G(y,p) p是x的质因数 那么可以把x质因数分解 看每个质数在y里面出现了多少次
那么对于质数p在1-n里面出现了多少次可以用logn的方法快速统计 即每次对n/p为数量和下一次的值
对于x质因数分解首先先求出1-sqrt的质数进行质因数分解 然后要看一下最后剩下的x是不是1 有可能存在大于sqrt(x)的质因子但是这样的质因子至多有一个
sqrt(x)*logn

#include 
#include 
#include 
#include 
#include 
#include 
#define int long long
using namespace std;
const int mod=1e9+7;
const int maxm=1e5+100;
int vis[maxm];
vector <int> prime;
int fast_pow(int x,int y)
{
	int ans=1;
	while(y)
	{
		if(y%2) ans=(1ll*ans*x)%mod;
		x=(1ll*x*x)%mod;
		y/=2;
	}
	return ans;
}
void init(int N)
{
	vis[1]=1;
	for(int i=2;i<=N;i++)
	{
		if(!vis[i]) prime.push_back(i);
		for(int j=0;j<prime.size()&&prime[j]*i<=N;j++)
		{
			vis[prime[j]*i]=1;
			if(i%prime[j]==0) break;
		}
	}
}
signed main()
{
	int n,x;
	init(1e5);
	cin>>x>>n;
	int ans=1;
	for(int i=0;i<prime.size();i++)
	if(x%prime[i]==0)
	{
		
		int num=prime[i];
		while(x%prime[i]==0)
			x/=prime[i];
		int p=n,tot=0;
		while(p)
		{
			tot+=p/num;
			p/=num;
		}
		//cout<
		ans=(1ll*ans*pow(num,tot))%mod;
	}
	cout<<ans<<endl;
	return 0;
}

你可能感兴趣的:(题目分析,算法竞赛)