Codeforces Round #633 (Div. 2)

Codeforces Round #633(Div.2)

\(A.Filling\ Diamonds\)
答案就是构成的六边形数量+1

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
using LL = int_fast64_t;
void solve(){
    LL n; cin >> n;
    cout << n << endl;
}
int main(){
    ____();
    int T;
    for(cin >> T; T; T--) solve();
    return 0;
}

\(B.Sorted\ Adjacent\ Differences\)
考虑排完序之后从中间开始一左一右选择即可

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 2e5+7;
int n,A[MAXN];
void solve(){
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> A[i];
    sort(A+1,A+1+n);
    int mid = n / 2 + 1;
    int lp = mid - 1, rp = mid + 1;
    cout << A[mid] << ' ';
    while(lp!=0 or rp!=n+1){
        if(lp!=0) cout << A[lp--] << ' ';
        if(rp!=n+1) cout << A[rp++] << ' ';
    }
    cout << endl;
}
int main(){
    ____();
    int T;
    for(cin >> T; T; T--) solve();    
    return 0;
}

\(C.Powered\ Addition\)
考虑对于每个数,需要加的最小值为其之前的最大值和这个值的差值,然后找到这个差值的最大值找到其二进制最高位即可

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
using LL = int_fast64_t;
int n;
LL A[MAXN];
void solve(){
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> A[i];
    LL minn = 1e10;
    LL delta = 0;
    for(int i = n; i >= 1; i--){
        delta = max(delta,A[i]-minn);
        minn = min(A[i],minn);
    }
    if(!delta) cout << 0 << endl;
    else{
        while(delta!=(delta&-delta)) delta -= (delta&-delta);
        cout << __builtin_ctz(delta)+1 << endl;
    }
}
int main(){
    ____();
    int T;
    for(cin >> T; T; T--) solve();
    return 0;
}

\(D.Edge\ Weight\ Assignment\)
考虑最少不同的数,各个叶子节点到根的距离的奇偶性如果一样,那么所有边权都可以相等,否则的话用\(1,2,3\)三个数来赋值边权必然可以满足条件
对于最多的不同的数,考虑树形\(DP\)\(dp[i]\)表示以\(i\)为根的子树所用的最多的不同边权,以非叶节点为根进行\(dfs\),考虑转移,对于\(u\)点的所有儿子,如果存在叶子节点的话,\(dp[u]+=1\),叶子节点连上来的边权必然相等,对于儿子中的非叶子节点\(v\),转移为\(dp[u] += dp[v] + 1\),可以假设叶子节点走到儿子节点的权值异或和为\(x\),那么不同儿子子树中的叶子节点走到该儿子节点的异或和可以不同,所以从儿子连到当前点的边权也可以不一样。

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
using LL = int_fast64_t;
int n,depth[MAXN],f[MAXN];
vector<int> G[MAXN];
bool odd = false, even = false;
void dfs(int u, int par){
    depth[u] = depth[par] + 1;
    bool zero = false;
    if(par and G[u].size()==1){
        if(depth[u]&1) odd = true;
        else even = true;
    }
    for(int v : G[u]){
        if(v==par) continue;
        dfs(v,u);
        if(f[v]==0) zero = true;
        else f[u] += f[v] + 1;
    }
    if(zero) f[u]++;
}
int main(){
    ____();
    cin >> n;
    for(int i = 1; i < n; i++){
        int u, v;
        cin >> u >> v;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
    }
    int root = 1;
    for(int i = 1; i <= n; i++) if(G[i].size()>1) root = i;
    dfs(root,0);
    cout << ((odd and even)?3:1) << ' ' << f[root] << endl;
    return 0;
}

\(C.Perfect\ Triples\)
找规律题
对着表找了半天规律没写出来,我菜死了
用四进制表示每一位,可以打表出来
001 002 003
//1行

010 020 030
011 022 033
012 023 031
013 021 032
//1<<2行

100 200 300
101 202 303
102 203 301
103 201 302
110 220 330
111 222 333
112 223 331
113 221 332
... ... ...
//1<<4行

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
using LL = int_fast64_t;
void solve(){
    LL n; cin >> n;
    LL m = (n - 1) / 3 + 1, md = n % 3 ? n % 3 : 3, ret = 0, bit = 1, num = 0, a[4];
    if(md==1) a[0] = 3, a[1] = 0, a[2] = 1, a[3] = 2;
    else if(md==2) a[0] = 1, a[1] = 0, a[2] = 2, a[3] = 3;
    else a[0] = 2, a[1] = 0, a[2] = 3, a[3] = 1;
    while(true){
        if(bit>=m){
            ret += (md<<num);
            break;
        }
        m -= bit;
        ret += (a[((m-1) / bit + 1) % 4]<<num);
        bit <<= 2, num += 2;
    }
    cout << ret << endl;
}
int main(){
    ____();
    int T;
    for(cin >> T; T; T--) solve();
    return 0;
}
posted @ 2020-04-13 01:20  _kiko  阅读(477)  评论(0编辑  收藏  举报