位运算


codeforces数学题,开拓一下思维,防止大脑生锈!
Time Limit: 2000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u

[]   [Go Back]   [Status]  

Description

Vasily the bear has got a sequence of positive integers a1, a2, ..., an. Vasily the Bear wants to write out several numbers on a piece of paper so that the beauty of the numbers he wrote out was maximum.

The beauty of the written out numbers b1, b2, ..., bk is such maximum non-negative integer v, that number b1andb2and...andbk is divisible by number 2v without a remainder. If such number v doesn't exist (that is, for any non-negative integer v, number b1andb2and...andbk is divisible by2v without a remainder), the beauty of the written out numbers equals -1.

Tell the bear which numbers he should write out so that the beauty of the written out numbers is maximum. If there are multiple ways to write out the numbers, you need to choose the one where the bear writes out as many numbers as possible.

Here expression xandy means applying the bitwise AND operation to numbers x and y. In programming languages C++ and Java this operation is represented by "&", in Pascal — by "and".

Input

The first line contains integer n (1 ≤ n ≤ 105). The second line contains n space-separated integers a1, a2, ..., an(1 ≤ a1 < a2 < ... < an ≤ 109).

Output

In the first line print a single integer k(k > 0), showing how many numbers to write out. In the second line print k integers b1, b2, ..., bk — the numbers to write out. You are allowed to print numbers b1, b2, ..., bk in any order, but all of them must be distinct. If there are multiple ways to write out the numbers, choose the one with the maximum number of numbers to write out. If there still are multiple ways, you are allowed to print any of them.

Sample Input

Input
5
1 2 3 4 5
Output
2
4 5
Input
3
1 2 4
Output
1
4


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

vector <int> ans;
int n;
int X[100005];

int main()
{
    scanf("%d",&n);

    for(int i=1;i<=n;i++)
    scanf("%d",&X[i]);

    for(int i=30;i>=0;i--)
    {
        ans.clear();
        int tmp=-1;
        for(int j=1;j<=n;j++)
        {
            if(X[j]&(1<<i))
            {
                ans.push_back(X[j]);
                if(tmp==-1)tmp=X[j];
                else tmp&=X[j];
            }
        }
        if(tmp%(1<<i)==0)break;
    }

    printf("%d\n%d",ans.size(),ans[0]);
    for(int i=1;i<ans.size();i++)
    printf(" %d",ans[i]);
    puts("");

    return 0;
}

E - Vasily the Bear and Fly
Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

Description

One beautiful day Vasily the bear painted 2m circles of the same radius R on a coordinate plane. Circles with numbers from 1 to m had centers at points (2R - R, 0)(4R - R, 0)...(2Rm - R, 0), respectively. Circles with numbers from m + 1 to 2m had centers at points (2R - R, 2R)(4R - R, 2R)...(2Rm - R, 2R), respectively.

Naturally, the bear painted the circles for a simple experiment with a fly. The experiment continued for m2 days. Each day of the experiment got its own unique number from 0 to m2 - 1, inclusive.

On the day number i the following things happened:

  1. The fly arrived at the coordinate plane at the center of the circle with number  ( is the result of dividing number x by number y, rounded down to an integer).
  2. The fly went along the coordinate plane to the center of the circle number  ( is the remainder after dividing number x by number y). The bear noticed that the fly went from the center of circle v to the center of circle u along the shortest path with all points lying on the border or inside at least one of the 2m circles. After the fly reached the center of circle u, it flew away in an unknown direction.

Help Vasily, count the average distance the fly went along the coordinate plane during each of these m2 days.

Input

The first line contains two integers m, R (1 ≤ m ≤ 1051 ≤ R ≤ 10).

Output

In a single line print a single real number — the answer to the problem. The answer will be considered correct if its absolute or relative error doesn't exceed 10 - 6.

Sample Input

Input
1 1
Output
2.0000000000
Input
2 2
Output
5.4142135624

观察这 2*m 个圆的圆心坐标不难发现,他们分成了上下两排,同一排相邻的两个圆相切,上下相邻的两个圆相切

再观察 fly 每次运动走的圆的分布规律,不难发现是每次选定一个下面的圆的圆心,分别以上面的圆的圆心为目的点走一次最短路,所以总共有 m2 次运动

那么一个最通常的想法就是:求出这 m2 次运动总共走过的距离

 

先看看最短路吧:

由于每次一定是一个圆在下面,一个圆在上面,那么可以这样搞:

    当两个圆相邻时(列号差为 0),最短路是 2R

    

    当两个圆的列号差为 1 时,最短路是 2R+2R

    

    当两个圆的列号差为 2 时,最短路是 2R+22R

    

    当两个圆的列号差为 3 时,最短路是 4R+22R

    

    当两个圆的列号差为 4 时,最短路是 6R+22R

    

    当两个圆的列号差为 5 时,最短路是 8R+22R

    ......

将他们存进一个数组 A 中,A[i] 表示列号差为 i 的最短路长度

以 m 为单位,看看每次运动的起始点和终止点

    前 m 次运动:起始点始终是下面第 1 个圆,终止点从上面第 1 个圆变化到第 m 个圆

    接下来的 m 次运动:起始点始终是下面第 2 个圆,终止点从上面第 1 个圆变化到第 m 个圆

    再接下来的 m 次运动:起始点始终是下面第 3 个圆,终止点从上面第 1 个圆变化到第 m 个圆

    ......

细心的读者在这里的时候估计已经知道该怎么做了,还没想出来的朋友可以接着往下看

 

从上面可以看出:起始点是在不停的往前走的,而终止点始终是上面的圆从 1 到 m

我们再以 m 为单位,看看他们的距离和

    前 m 次运动的距离和我们可以求出来:sum1=∑A[i]

    那么接下来的 m 次运动的距离和呢:sum2=sum-A[m-1]+A[1]

    再接下来的的 m 次运动的距离和呢:sum3=sum2-A[m-2]+A[2]

    第 4 个 m 次运动的距离和:sum4=sum3-A[m-3]+A[3]

    ......

相信看到这里,大家都知道该怎么做了 o(m) 的扫一遍,用两个指针辅助,这样就可以求出来了

 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

const int N=100006;

int m;
double R, A[N];

void init() {
    A[0]=2, A[1]=2+sqrt(2);
    for(int i=2; i<m; i++) A[i]=2*(i-1)+2*sqrt(2);
}

int main() {
    scanf("%d%lf", &m, &R);
    init();
    double ans=0;
    for(int i=0; i<m; i++) {
        ans+=A[i];
    }
    int p1=1, p2=m-1;
    double last=ans;
    for(int i=1; i<m; i++) {
        last=last-A[p2]+A[p1];
        ans+=last;
        p1++, p2--;
    }
    printf("%lf\n", ans/m/m*R);
    return 0;
}

B


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值