Codeforces Round #520 (Div. 2)

 题目链接:http://codeforces.com/contest/1062

A 题

题意:给你一个升序序列,问你最多删除多少个,还可以让那个人复原回来。

思想:想复原只有1到一个数或者一个数到1000或者中间一段距离,对于前两者最长就是长度-1  后者就是长度-2.

B题

题意:给你一个n问你可以通过*X或者开根号(能够正好开),求算出来的最小的数和最小的次数

思想:最小数的那个数肯定是n的素因子的乘积,所以就算一下n的素因子,然后考虑将每个因子一步乘到2^x次方,然后一直开根号就行。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
ll a[maxn];
int main()
{
	ll n,m,Min=1;
	int ans=0,k=0;
	scanf("%lld",&n);
	m=n;
	ll temp = sqrt(n);
	for(int i=2;i<=temp;i++)
	{
		if(n%i==0)
		{
			int sum=0;
			while(n%i==0)
			{
				a[k]++;
				sum++;
				n=n/i;
			}
			Min*=i;
			ans=max(ans,sum);
			k++;
		}
	}
	if(n>1)
	{
		Min*=n;
		a[k++]++;
	}
	if(ans<=1)
	{
		printf("%lld %d\n",m,0);
		return 0;
	}
	ll sum=1;
	int cnt=0;
	while(sum<ans)
	{
		sum=sum*2;
		cnt++;
	}
	for(int i=0;i<k;i++)
		if(a[i]<sum)
		{
			cnt++;
			break;
		}
	printf("%lld %d\n",Min,cnt);
	return 0;
} 

C

题意:给你一个01串有q次询问,每次问你一个区间如何弄让按个值最大,假如你当前获得Xi,那么区间没有被拿的数都增加xi。

思想:贪心,推公式,写一下发现1的是一个以1为开始等比为2的序列,0的就是1最大的那个序列减1,0也变成了一个等比为2的序列。求和即可。需要特判下全0的情况。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const long long mod = 1e9+7;
typedef long long ll;
int ans[maxn];
char str[maxn];
ll Qpow(ll a,int b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)
			ans=(ans*a)%mod;
		a=(a*a)%mod;
		b=b/2;
	}
	return ans;
}
int main()
{
	int n,q;
	scanf("%d%d",&n,&q);
	scanf("%s",str);
	for(int i=0;i<n;i++)
	{
		if(str[i]=='1')
			ans[i+1]=ans[i]+1;
		else
			ans[i+1]=ans[i];
	} 
	while(q--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		ll temp = ans[r]-ans[l-1];
		ll t=(r-l+1-temp);//0的个数
		if(temp==0)
			printf("0\n");
		else
		{
			ll tt=(Qpow(2ll,(long long)(temp+t))-Qpow(2ll,t)+mod)%mod;
			printf("%lld\n",tt);
		} 
	}
	return 0;
} 

D

题意:给你一个n问你有多少个序列对满足1< |a| |b| <=n 问你有多少满足的序列。(我大概理解的就是这样,如果不对请指正)

同时满足a*x=b 或者 b*x=a |x|>1 

思想:暴力枚举a x    就可以发现对于每个满足的值它的绝对值会出现4次 比如 (2,2) (2,-2) (-2,2) (-2,-2)

所以暴力枚举就行了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	ll n;
	scanf("%lld",&n);
	ll ans = 0;
	for(int i=2;i<=n;i++)
		for(int j=2;j*i<=n;j++)	
			ans=ans+(j*4);
	printf("%lld\n",ans);
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值