1. 程式人生 > >CF-1110(2019/02/08)

CF-1110(2019/02/08)

\n puts name 個數 一段 -m else clas 最大的

CF-1110

A. Parity

  • 快速冪的思想,考慮最後一位即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll b,k;
ll a[100010];
int main(){
    scanf("%lld%lld",&b,&k);
    for(int i=0;i<k;i++)
        scanf("%lld",&a[i]);
    ll ans = 0;
    ll base = 1;
    for(int i=0;i<k;i++){
        ans = (ans+a[k-i-1]*base)%10;
        base = base*b%10;
    }
    if(ans%2)puts("odd");
    else puts("even");
    return 0;
}

可以再多想一想。

? \[n = a_1\cdot b^{k-1} + a_2\cdot b^{k-2} + \cdots + a_{k-1} \cdot b + a_k\]

  • b為偶數時,n的奇偶性只與\(a_k\) 有關
  • b為奇數時,\(b^k\) 為奇數,所有n的奇偶性只與 a 序列中奇數個數有關。
#include<bits/stdc++.h>
using namespace std;
int b,k,i,x,y;
int main(){
    for(cin>>b>>k;i<k;i++)
        cin>>x,y+=x%2;
    cout<<((b%2?y%2:x%2)?"odd":"even");
}

B. Tape

n == k 時直接輸出 n 就好

n <= k 時,一些點要合並,由於合並產生的操作可能會使一段上面有多個點,所以我們要先把 k 個點都用長度為 1 的去填好。之後合並的時候只需要考慮點與點之間的距離即可(YY一下,你就知道)

  • 當 k 等於 n,則直接輸出 n
  • 當 k 小於 n,則先把k段用長度為1補齊,再加上 (n-k) 段比較小的距離。
#include <bits/stdc++.h>
using namespace std;
int n,m,k;
int a[100010];
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(int i=n-1;i>0;i--)
        a[i] = a[i]-a[i-1];
    sort(a+1,a+n);
    int ans = k;
    for(int i=1;i<=(n-k);i++)
        ans += a[i];
    cout<<ans<<endl;
    return 0;
}

C. Meaningless Operations

根據 Note 可以得知只要湊出一個 0 ,就可能得到最大的gcd。

  • \(a\neq (2^x -1)\) , 則一定可以找到一個 b 使得

    • $ a \oplus b = 2^x -1$ , \(a \& b = 0\)
  • \(a = (2^x - 1)\) ,則可以發現

    ? \[gcd( a\oplus b, a\&b) = gcd(2^x-1-b,b) = gcd(2^x-1,b)\]

    • 因為 \(gcd(x,x+y) = gcd(x,y)\)
    • 所以只需要找到 a 的最大因數(非a) 即可。
  • 復雜度\(O(q\sqrt m)\) 。但是可以打表做(也可以直接暴力求)

#include <bits/stdc++.h>
using namespace std;
int po[30];
int res[30] = {0,1,1,1,5,1,21,1,85,73,341,89,1365,1,5461,4681,21845,1,87381,1,349525,299593,1398101,178481,5592405,1082401,22369621};
void init(){
    po[0] = 1;
    for(int i=1;i<30;i++)
        po[i] = po[i-1]*2;
}
bool check(int x){
    for(int i=1;i<30;i++)
        if(x==po[i]-1)
            return true;
    return false;
}
int calc(int x){
    int num =0;
    while(x)
    {
        x/=2;
        num++;
    }
    return num;
}
int main(){
    init();
    int q;
    cin>>q;
    while(q--){
        int n;
        cin>>n;
        if(check(n)){
            int num = calc(n);
            cout<<res[num]<<endl;
        }
        else{
            for(int i=1;i<30;i++){
                if(n>=po[i]&&n<po[i+1]){
                    cout<<po[i+1]-1<<endl;
                    break;
                }
            }
        }
    }
}

CF-1110(2019/02/08)