Codeforces Round #554 (Div. 2)(A,B)补题(C)未补完(D,E,F1,F2)

A. Neko Finds Grapes

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

On a random day, Neko found nn treasure chests and mm keys. The ii-th chest has an integer aiai written on it and the jj-th key has an integer bjbj on it. Neko knows those chests contain the powerful mysterious green Grapes, thus Neko wants to open as many treasure chests as possible.

The jj-th key can be used to unlock the ii-th chest if and only if the sum of the key number and the chest number is an odd number. Formally, ai+bj≡1(mod2)ai+bj≡1(mod2). One key can be used to open at most one chest, and one chest can be opened at most once.

Find the maximum number of chests Neko can open.

Input

The first line contains integers nn and mm (1≤n,m≤1051≤n,m≤105) — the number of chests and the number of keys.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109) — the numbers written on the treasure chests.

The third line contains mm integers b1,b2,…,bmb1,b2,…,bm (1≤bi≤1091≤bi≤109) — the numbers written on the keys.

Output

Print the maximum number of chests you can open.

Examples

input

Copy

5 4
9 14 6 2 11
8 4 7 20

output

Copy

3

input

Copy

5 1
2 4 6 8 10
5

output

Copy

1

input

Copy

1 4
10
20 30 40 50

output

Copy

0

Note

In the first example, one possible way to unlock 33 chests is as follows:

  • Use first key to unlock the fifth chest,
  • Use third key to unlock the second chest,
  • Use fourth key to unlock the first chest.

In the second example, you can use the only key to unlock any single chest (note that one key can't be used twice).In the third example, no key can unlock the given chest.

原地址在这里

题意:

一个n,m,然后接着一行是n个数a[i],接着m个数b[i],然后问你是否可以找到两个数相加%2为1的数,然后问你能得到的最大的组数是多少。

题解:

我们可以推导出只有偶数加奇数菜能得到奇数,所以就变成了,总共可以得到多少得奇数个偶数得组合在n和m两排数中,然后分别求出两排数得奇数个数和偶数个数,分别组合去最小,在加起来就行了。

代码:

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

int main()
{
    int n , m ;
    scanf("%d%d" , &n ,  &m) ;
    int oa = 0 , ob = 0 , ea = 0 , eb = 0 ;
    for(int i = 0 ; i < n ; i ++){
        int x ;
        scanf("%d" , &x) ;
        if(x & 1) oa ++ ;
        else ea ++ ;
    }
    for(int i = 0 ; i < m ; i ++){
        int x ;
        scanf("%d" , &x) ;
        if(x & 1) ob ++ ;
        else eb ++ ;
    }
    int ans = min(oa , eb) + min(ob , ea) ;
    printf("%d\n" , ans) ;
    return 0 ;
}

B. Neko Performs Cat Furrier Transform

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Cat Furrier Transform is a popular algorithm among cat programmers to create longcats. As one of the greatest cat programmers ever exist, Neko wants to utilize this algorithm to create the perfect longcat.

Assume that we have a cat with a number xx. A perfect longcat is a cat with a number equal 2m−12m−1 for some non-negative integer mm. For example, the numbers 00, 11, 33, 77, 1515 and so on are suitable for the perfect longcats.

In the Cat Furrier Transform, the following operations can be performed on xx:

  • (Operation A): you select any non-negative integer nn and replace xx with x⊕(2n−1)x⊕(2n−1), with ⊕⊕ being a bitwise XOR operator.
  • (Operation B): replace xx with x+1x+1.

The first applied operation must be of type A, the second of type B, the third of type A again, and so on. Formally, if we number operations from one in the order they are executed, then odd-numbered operations must be of type A and the even-numbered operations must be of type B.

Neko wants to produce perfect longcats at industrial scale, thus for each cat Neko only wants to perform at most 4040 operations. Can you help Neko writing a transformation plan?

Note that it is not required to minimize the number of operations. You just need to use no more than 4040 operations.

Input

The only line contains a single integer xx (1≤x≤1061≤x≤106).

Output

The first line should contain a single integer tt (0≤t≤400≤t≤40) — the number of operations to apply.

Then for each odd-numbered operation print the corresponding number nini in it. That is, print ⌈t2⌉⌈t2⌉ integers nini (0≤ni≤300≤ni≤30), denoting the replacement xx with x⊕(2ni−1)x⊕(2ni−1) in the corresponding step.

If there are multiple possible answers, you can print any of them. It is possible to show, that there is at least one answer in the constraints of this problem.

Examples

input

Copy

39

output

Copy

4
5 3 

input

Copy

1

output

Copy

0

input

Copy

7

output

Copy

0

Note

In the first test, one of the transforms might be as follows: 39→56→57→62→6339→56→57→62→63. Or more precisely:

  1. Pick n=5n=5. xx is transformed into 39⊕3139⊕31, or 5656.
  2. Increase xx by 11, changing its value to 5757.
  3. Pick n=3n=3. xx is transformed into 57⊕757⊕7, or 6262.
  4. Increase xx by 11, changing its value to 63=26−163=26−1.

In the second and third test, the number already satisfies the goal requirement.

原地址在这里

题意:

给你一个数,有两种操作:

1、对这个数进行异或操作,异或得值是选取一个n,异或(2^n-1(^是次方))

2、对当前这个数进行加1

你只能对这个数不断进行1,2,1,2,1,1........这样得重复操作,并且是从1开始的,要你求最小的操作数,当你将这个数变成(2^x-1)(x=1,2,3,4......)就结束了。

题解:

首先你要异或一个数是(2^n-1),根据异或的性质,可以知道,按二进制来看,你只有当前为值为0才需要进行异或来变成1,因为你需要变成全是1,而且你异或的也是一个确实1的数,这样的话,你只需要找到最大位的零前一位的位置的2的次方数-1就是你需要异或的值了,这样,你就可以不改变前面的值,又可以改变后面的0,这样你就是最小的了。

代码:

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

ll a[45] ;
int anss[50] ;

int main()
{
    for(int i  = 0 ; i <= 40 ; i ++) a[i] = pow(2 * 1ll , i) ;
    memset(anss , 0 , sizeof(anss)) ;
    ll n ;
    scanf("%I64d" , &n) ;
    int ans = 0 ;
    int t = 0 ;
    for(int i = 1 ; 3; i ++)
    {
        int x = (int)(log(n) / log(2 * 1ll)) ;
        for(; (n & a[x]) ; -- x) ;
        x ++ ;
        if(n == (a[x] - 1) || x == 0) break ;
        if(i & 1) n ^= (a[x] - 1) , anss[t ++] = x ;
        else ++ n ;
        ans ++ ;
    }
    printf("%d\n" , ans) ;
    if(ans)
    {
        for(int i = 0 ; i < t - 1 ; i ++) printf("%d " ,anss[i]) ;
        printf("%d\n" , anss[t - 1]) ;
    }
    return 0 ;
}

补题:

C. Neko does Maths

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Neko loves divisors. During the latest number theory lesson, he got an interesting exercise from his math teacher.

Neko has two integers aa and bb. His goal is to find a non-negative integer kk such that the least common multiple of a+ka+k and b+kb+k is the smallest possible. If there are multiple optimal integers kk, he needs to choose the smallest one.

Given his mathematical talent, Neko had no trouble getting Wrong Answer on this problem. Can you help him solve it?

Input

The only line contains two integers aa and bb (1≤a,b≤1091≤a,b≤109).

Output

Print the smallest non-negative integer kk (k≥0k≥0) such that the lowest common multiple of a+ka+k and b+kb+k is the smallest possible.

If there are many possible integers kk giving the same value of the least common multiple, print the smallest one.

Examples

input

Copy

6 10

output

Copy

2

input

Copy

21 31

output

Copy

9

input

Copy

5 10

output

Copy

0

Note

In the first test, one should choose k=2k=2, as the least common multiple of 6+26+2 and 10+210+2 is 2424, which is the smallest least common multiple possible.

原地址在这里

题意:

给你两个数,让你求一个数k,是否可以在两个数的加k过后,得到这两个数最小的最小公倍数,这样问你k是多少。

题解:

题目比较简单,做真的弄死我了

两个数的最小公倍数也就是gcd(a,b),根据更相减损术的原理,再a <=b的时候是可以求gcd(b-a,a)的最大公约数,和原来的最大公约数是一致的,而且我们要求的两个数再加k后的乘积更加大了,既然这样,为什么最小公倍数还变小呢?那是因为它除了一个数,那就是最大公约数,当这个最大公约数越大那么就整体就小下来了,那么由gcd(b-a,a),那么我们可以枚举b-a的因子,因为b-a的因子中当找到满足的最大公约数的时候,那么其一定是a 和b 的最大公约数,那么就得到答案了,那个k你需要找到大于a的最小的满足的数,那么你就可以这样((a/v[i] + 1) * v[i] - a) ,这样得到的数就是大于a的最小的满足的数,因为当前的数除以满足的的到整数加一再乘以减去后a就是再v[i]下最小的k了。

代码:

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

ll gcd(ll a , ll b){return a ? gcd(b % a , a) : b ;}

int main()
{
    ll a , b ;
    scanf("%I64d%I64d" , &a , &b) ;
    if(a < b) swap(a , b) ;
    ll lc = (a * b) / gcd(a , b) ;
    ll k = a - b , ans = 0 ;
    vector<ll> v ;
    for(ll i = 1 ; i <= sqrt(k) ; i ++)
    {
        if(k % i) continue ;
        v.push_back(i) ;
        if(k / i != i) v.push_back(k / i) ;
    }
    for(int i = 0 ; i < v.size() ; i ++)
    {
        int k1 = (a / v[i] + 1) * v[i] - a ;
        if((a + k1) * (b + k1) / gcd(a + k1 , b + k1) < lc) lc = (a + k1) * (b + k1) / gcd(a + k1 , b + k1) , ans = k1 ;
    }
    printf("%I64d\n" , ans) ;
    return 0 ;
}

菜得不一样,菜出新高度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值