【codeforces #276(div 1)】ABD题解

A. Bits
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Let's denote as  the number of bits set ('1' bits) in the binary representation of the non-negative integer x.

You are given multiple queries consisting of pairs of integers l and r. For each query, find the x, such that l ≤ x ≤ r, and  is maximum possible. If there are multiple such numbers find the smallest of them.

Input

The first line contains integer n — the number of queries (1 ≤ n ≤ 10000).

Each of the following n lines contain two integers li, ri — the arguments for the corresponding query (0 ≤ li ≤ ri ≤ 1018).

Output

For each query print the answer in a separate line.

Sample test(s)
input
3
1 2
2 4
1 10
output
1
3
7
Note

The binary representations of numbers from 1 to 10 are listed below:

110 = 12

210 = 102

310 = 112

410 = 1002

510 = 1012

610 = 1102

710 = 1112

810 = 10002

910 = 10012

1010 = 10102



分两种情况考虑:

1.l和r的二进制拆分之后位数不同:

如果r是11111...那么答案就是r;否则是答案是11111..比l少1位


2.l和r的二进制拆分之后位数相同:

从前往后扫到不相同的那一位k,如果r从k以后全是1,答案就是r;否则答案是前k位+1111...(k+1位到最后一位都是1)

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#define LL long long
using namespace std;
int a[3][1000],n;
void chai(LL x,int k)
{
	a[k][0]=0;
	while (x)
	{
		a[k][0]++;
		int s=a[k][0];
		if (x&1) a[k][s]=1;
		else a[k][s]=0;
		x>>=1;
	}
}
int main()
{
	int n;
	cin>>n;
	while (n--)
	{
		LL l,r;
		cin>>l>>r;
		if (l==r)
		{
			cout<<l<<endl;
			continue;
		}
		chai(l,0);
		chai(r,1);
		if (a[0][0]<a[1][0])
		{
			LL ans=0,b=1;
			for (int i=1;i<a[1][0];i++)
				ans+=b,b<<=1LL;
			if (ans+b==r) ans=r;
			cout<<ans<<endl;
		}
		else
		{
			int k=0;
			for (int i=a[0][0];i;i--)
			{
				if (a[0][i]!=a[1][i])
				{
					k=i;
					break;
				}
			}
			LL ans=0,b=1;
			for (int i=1;i<k;i++)
				ans+=b,b<<=1LL;
			int ok=1;
			for (int i=1;i<=k;i++)
			{
				if (!a[1][i]) ok=0;
			}
			if (ok) ans+=b;
			b<<=1LL;
			for (int i=k+1;i<=a[0][0];i++)
				ans+=(b*a[0][i]),b<<=1;
			cout<<ans<<endl;
		}
	}
	return 0;
}


B. Maximum Value
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a sequence a consisting of n integers. Find the maximum possible value of  (integer remainder of aidivided by aj), where 1 ≤ i, j ≤ n and ai ≥ aj.

Input

The first line contains integer n — the length of the sequence (1 ≤ n ≤ 2·105).

The second line contains n space-separated integers ai (1 ≤ ai ≤ 106).

Output

Print the answer to the problem.

Sample test(s)
input
3
3 4 5
output
2


如果枚举ai,复杂度是O(n^2),那么我们可以枚举aj!


x=aj*k+b,k相同,要让b最大则让x最大。


我们枚举k,要找到>aj*k且<aj*(k+1)的最大数。


就相当于找最接近aj*(k+1)的数,那么我们预处理出m[i]表示<=i的最大数是几。


(注释掉的是nlognlogn的做法,会TLE)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <set>
#define mp make_pair
#define M 200000+5
using namespace std;
int n,a[M],v[2000000+5],m[2000000+5];
set<pair<int,int> > s;
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	sort(a+1,a+1+n);
	int tot=0;
	for (int i=2;i<=n;i++)
		if (a[i]!=a[i-1])
		{
			a[++tot]=a[i-1];
		}
	a[++tot]=a[n];
	n=tot;
	for (int i=1;i<=n;i++)
		v[a[i]]=a[i];
	for (int i=1;i<=a[n]*2;i++)
		m[i]=max(m[i-1],v[i]);
	int ans=0;
	for (int i=1;i<n;i++)
		for (int j=a[i]*2;j<=a[n]*2;j+=a[i])
			ans=max(ans,a[i]+m[j-1]-j);
	/*for (int i=1;i<n;i++)
	    s.insert(mp(a[n]/a[i]*a[i],i));
	int ans=0;
	for (int i=n;i>1;i--)
	{
		if (a[i-1]<=ans) break;
		ans=max(ans,a[i]-s.begin()->first);
		int fi=s.rbegin()->first,se=s.rbegin()->second;
		while (i>2&&fi>a[i-1])
		{
			s.erase(mp(fi,se));
			if (se<i-1)
				s.insert(mp(a[i-1]/a[se]*a[se],se));
		    fi=s.rbegin()->first,se=s.rbegin()->second;
		}
	}*/
	printf("%d\n",ans);
	return 0;
}


D. Kindergarten
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

In a kindergarten, the children are being divided into groups. The teacher put the children in a line and associated each child with his or her integer charisma value. Each child should go to exactly one group. Each group should be a nonempty segment of consecutive children of a line. A group's sociability is the maximum difference of charisma of two children in the group (in particular, if the group consists of one child, its sociability equals a zero).

The teacher wants to divide the children into some number of groups in such way that the total sociability of the groups is maximum. Help him find this value.

Input

The first line contains integer n — the number of children in the line (1 ≤ n ≤ 106).

The second line contains n integers ai — the charisma of the i-th child ( - 109 ≤ ai ≤ 109).

Output

Print the maximum possible total sociability of all groups.

Sample test(s)
input
5
1 2 3 1 2
output
3
input
3
3 3 3
output
0
Note

In the first test sample one of the possible variants of an division is following: the first three children form a group with sociability 2, and the two remaining children form a group with sociability 1.

In the second test sample any division leads to the same result, the sociability will be equal to 0 in each group.


贪心。


ans表示当前的最大答案是多少;


s表示(前k个数的最大答案-a[k+1])的最大值;


l表示(前p个数的最大答案+a[p+1])的最大值;


那么当扫描到a[i]时,更新s,l,ans(见代码)

#include <iostream>
#include <algorithm>
#include <cstdio>
#define LL long long
using namespace std;
LL ans,s,l;
int main()
{
	int n;
    scanf("%d",&n);
	LL x;
	scanf("%I64d",&x);
	ans=0,s=-x,l=x;
	for (int i=1;i<n;i++)
	{
	    scanf("%I64d",&x);
		if (ans-x>s)
			s=ans-x;
		if (ans+x>l)
			l=ans+x;
		ans=max(ans,max(s+x,l-x));
	}
	cout<<ans<<endl;
	return 0;
}


感悟:

D题值得借鉴,简单巧妙~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值