2021.10.23 组队选拔赛

比赛链接
A.Find Subsequence

B.operation
区间DP

  • ((a & b) + (a | b)) >> 1 = (a + b)/2
点击查看代码
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int maxn = 1e3 + 10;

int dp[200][200][10];
int n;

int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int a;
        scanf("%d", &a);
        dp[i][i][a] = 1;
    }

    for(int len = 2; len <= n; len ++){
        for(int i = 1; i < n; i ++){
            int j = i + len - 1;
            if(j > n)break;

            for(int k = i; k < j; k ++){
                for(int p1 = 0; p1 <= 7; p1 ++){
                    for(int p2 = 0; p2 <= 7; p2 ++){
                        if(dp[i][k][p1] && dp[k + 1][j][p2]){
                            dp[i][j][p1 + p2 >> 1] = 1;
                        }
                    }
                } 
            }
        }
    }

    for(int i = 0; i <= 7; i ++){
        if(dp[1][n][i])printf("%d ", i);
    }
    return 0;
}

C.FQ之旅

D.SumMin
最短路floyd算法。

点击查看代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
const int maxn = 5e2 + 10;
using ll = long long;

ll dp[maxn][maxn];
int n, ret[maxn];

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= n; j ++) {
            scanf("%lld", &dp[i][j]);
        }
    }
    for(int i = n; i >= 1; i --)scanf("%d", &ret[i]);
    
    vector<ll> v;
    for(int k = 1; k <= n; k ++) {
        for(int i = 1; i <= n; i ++) {
            for(int j = 1; j <= n; j ++) {
                int u = ret[i], v = ret[j];
                dp[u][v] = min(dp[u][v], dp[u][ret[k]] + dp[ret[k]][v]);
            }
        }

        ll ans = 0;
        for(int i = 1; i <= k; i ++) {
            for(int j = 1; j <= k; j ++) {
                if(i == j)continue;
                ans += dp[ret[i]][ret[j]];
            }
        }
        v.push_back(ans);
    }

    for(int i = v.size() - 1; i >= 0; i --)printf("%lld ", v[i]);
    return 0;
}

E.Number Game
\(bfs\)

点击查看代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <unordered_map>

#define fi first
#define se second
#define pb push_back
// #define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long

const double eps = 1e-5;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const int maxn = 2e6 + 10;

using namespace std;

int n, k;
bool ban[20], vis[maxn];
vector<int> v;
int rd[maxn], pre[maxn];

int main(){
    memset(pre, -1, sizeof pre);
    scanf("%d%d", &k, &n);
    for(int i = 1; i <= n; i ++){
        int a; scanf("%d", &a);
        ban[a] = true;
    }
    for(int i = 0; i <= 9; i ++){
        if(!ban[i])v.pb(i);
    }

    queue<int> q;
    int len = v.size();
    for(int i = 0; i < len; i ++){
        if(!v[i])continue;
        int a = v[i] % k;
        if(vis[a])continue;
        vis[a] = 1, rd[a] = v[i];
        q.push(a);
    }

    while(q.size()){
        int p = q.front(); q.pop();
        if(!p){
            vector<int> ans;
            for(int i = p; ~i; i = pre[i]){
                ans.pb(rd[i]);
            }
            reverse(all(ans));
            for(int i : ans)printf("%d", i);
            return 0;
        }
        for(int i = 0; i < len; i ++){
            int a = (p * 10 + v[i]) % k;
            if(vis[a])continue;
            vis[a] = 1;
            rd[a] = v[i], pre[a] = p;
            q.push(a);
        }
    }
    puts("-1");
    return 0;
}

F.Number Game2
容斥原理

点击查看代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <unordered_map>

#define fi first
#define se second
#define pb push_back
// #define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long

const double eps = 1e-5;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;

using namespace std;

int n;
ll s[maxn];
ll fac[maxn], inv[maxn], c[maxn];

ll qpow(ll a, ll b = mod - 2){
    ll ret = 1;
    while(b){
        if(b & 1)ret = ret * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return ret;
}

void init(int sum, int n){
    fac[0] = inv[0] = 1;
    for(int i = 1; i <= n; i ++){
        fac[i] = fac[i - 1] * i % mod;
        inv[i] = inv[i - 1] * qpow(2) % mod;
    }
    c[0] = 1;
    for(int i = 1; i <= sum; i ++){
        c[i] = c[i - 1] * (sum - i + 1) % mod * qpow(i) % mod;
    }
}

int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)scanf("%lld", &s[i]);
    sort(s + 1, s + n + 1);
    int sum = 0;
    for(int i = 1; i <= n; i ++){
        if(s[i] == s[i + 1])sum ++;
    }
    init(sum, n);
    ll ans = fac[n] * qpow(qpow(2, sum)) % mod, ret = 0;

    for(int i = 1; i <= sum; i ++){
        ll a = c[i] * (fac[n - i] * inv[sum - i] % mod) % mod;
        if(i & 1)ret = (ret + a) % mod;
        else ret = (ret - a) % mod;
    }

    ans = (ans - ret + mod) % mod;
    printf("%lld\n", ans);
    return 0;
}

G.小郑的疑惑
\(O(nlogn)\)的因子分解筛法

点击查看代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <unordered_map>

#define fi first
#define se second
#define pb push_back
// #define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long

const double eps = 1e-5;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const int maxn = 2e6 + 10;

using namespace std;

int n, m;
int s[maxn];
ll sum[maxn], ans[maxn];
ll vis[maxn], cnt[maxn];

int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++){
        scanf("%d", &s[i]);
        vis[s[i]] ++;
    }

    for(int i = 1; i <= m; i ++) {
        for(int j = i; j <= m; j += i) {
            int a = j / i;
            if(a < i)continue;
            if(a == i)cnt[j] += vis[a] * (vis[a] - 1) / 2;
            else cnt[j] += vis[a] * vis[i];
        }
    }

    for(int i = 1; i <= m; i ++){
        for(int j = i; j <= m; j += i){
           ans[j] += cnt[i];
        }
    }

    for(int i = 1; i <= m; i ++)printf("%lld ", ans[i]);
    return 0;
}

H.签到题
字典树

点击查看代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <unordered_map>

#define fi first
#define se second
#define pb push_back
// #define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long

const double eps = 1e-5;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const int maxn = 2e6 + 10;

using namespace std;

int t[maxn][2], tot = 1;
int sum = INT32_MAX;

void insert(int d){
    int rt = 1;
    for(int i = 31; i >= 0; i --){
        int a = (d >> i) & 1;
        if(!t[rt][a])t[rt][a] = ++ tot;
        rt = t[rt][a]; 
    }
}

void dfs(int rt, int ret, int xorr){
    if(!t[rt][0] && !t[rt][1]){
        if(xorr < sum)sum = xorr;
        return ;    
    }

    if(t[rt][0] && t[rt][1]){
        dfs(t[rt][0], ret * 2 + 1, xorr * 2 + 1);
        dfs(t[rt][1], ret * 2, xorr * 2 + 1);
    }
    else if(t[rt][1]){
        dfs(t[rt][1], ret * 2 + 1, xorr * 2);
    }
    else if(t[rt][0]){
        dfs(t[rt][0], ret * 2, xorr * 2);
    }
}

int main(){
    int n; scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int a;
        scanf("%d", &a);
        insert(a);
    }

    dfs(1, 0, 0);
    printf("%d\n", sum);
    return 0;
}

I.一道题
单调栈 + 思维

点击查看代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <stack>
#include <unordered_map>
#include <bitset>

#define fi first
#define se second
#define pb push_back
// #define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long

const double eps = 1e-5;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const int maxn = 2e5 + 10;

using namespace std;
#define lson rt << 1
#define rson rt << 1 | 1

unordered_map<int, int> mp;
int n, s[maxn];
int l[maxn], r[maxn];
int wl[maxn], wr[maxn], p[40];

void initlr(){
    stack<int> st;
    for(int i = 1; i <= n; i ++){
        while(st.size() && s[i] >= s[st.top()])st.pop();
        l[i] = st.size() ? st.top() + 1 : 1;
        st.push(i);
    }

    while(st.size())st.pop();
    for(int i = n; i >= 1; i --){
        while(st.size() && s[i] >= s[st.top()])st.pop();
        r[i] = st.size() ? st.top() - 1 : n;
        st.push(i);
    }
}

void initwlr(){
    memset(wl, -1, sizeof wl), memset(wr, inf, sizeof wr);
    for(int i = 1; i <= n; i ++){
        for(int j = 0; j <= 31; j ++){
            int a = (s[i] >> j) & 1;
            if(!a && p[j])wl[i] = max(wl[i], p[j]);
        }
        for(int j = 0; j <= 31; j ++){
            int a = (s[i] >> j) & 1;
            if(a)p[j] = i;
        }
    }
    memset(p, 0, sizeof p);
    for(int i = n; i >= 1; i --){
        for(int j = 0; j <= 31; j ++){
            int a = (s[i] >> j) & 1;
            if(!a && p[j])wr[i] = min(wr[i], p[j]);
        }
        for(int j = 0; j <= 31; j ++){
            int a = (s[i] >> j) & 1;
            if(a)p[j] = i;
        }
    }
}

int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)scanf("%d", &s[i]);
    initlr(), initwlr();

    ll sum = 0;
    for(int i = 1; i <= n; i ++){
        int pos1, pos11, pos22, pos2;
        pos1 = max(mp[s[i]], l[i]), pos2 = r[i];
        mp[s[i]] = i + 1;
        pos11 = wl[i], pos22 = wr[i];

        if(i == pos1 && pos2 == i)continue;
        if(pos1 <= pos11 && pos22 <= pos2){
            sum += 1ll * (i - pos1 + 1) * (pos2 - i + 1) - 1ll * (i - pos11) * (pos22 - i);
        }
        else if(pos1 <= pos11){
            sum += 1ll * (pos2 - i + 1) * (pos11 - pos1 + 1);
        }
        else if(pos22 <= pos2){
            sum += 1ll * (i - pos1 + 1) * (pos2 - pos22 + 1);
        }
    }
    printf("%lld\n", sum);
    return 0;
}

J.City Union
线性基+并查集

点击查看代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <unordered_map>

#define fi first
#define se second
#define pb push_back
// #define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long

const double eps = 1e-5;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const int maxn = 2e5 + 10;

using namespace std;

int x[maxn][40];
int fa[maxn], s[maxn];
int vis[maxn], n, m;

int fid(int a){
    return a == fa[a] ? a : fa[a] = fid(fa[a]);
}

bool check(int a, int p){
    for(int i = 31; i >= 0; i --){
        if((a >> i) & 1){
            a ^= x[p][i];
        }
    }
    if(!a)return true;
    else return false;
}

void union1(int a, int b){
    for(int i = 0; i <= 31; i ++){
        if(!x[b][i])continue;
        int ret = x[b][i];
        for(int j = 31; j >= 0; j --){
            if((ret >> j) & 1){
                if(x[a][j])ret ^= x[a][j];
                else{x[a][j] = ret; break;}
            }
        }
    }
}

int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++){
        scanf("%d", &s[i]);
        for(int j = 31; j >= 0; j --){
            if((s[i] >> j) & 1){
                x[i][j] = s[i];
                break;
            }
        }
    }
    for(int i = 1; i <= n; i ++)fa[i] = i;

    int a, b, c;
    for(int i = 1; i <= m; i ++){
        scanf("%d%d%d", &a, &b, &c);
        int p, xx = fid(a), yy = fid(b);

        if(xx != yy){
            fa[xx] = yy;
            union1(yy, xx);
        }

        if(check(c, yy))puts("Yes");
        else puts("No");
    }
    return 0;
}
posted @ 2021-10-26 23:58  lniiwuw  阅读(47)  评论(0)    收藏  举报