zoukankan      html  css  js  c++  java
  • Codeforces Round #470 (Div 2) B 数学 C 二分+树状数组 D 字典树

    Codeforces Round #470

    B. Primal Sport

    数学题,对 x2 和 x1 分解质因子即可。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005;
    
    int p1[N], cnt1;
    void get(int x, int* p, int &num)
    {
        num = 0;
        for(int i=2; i<=sqrt(x); ++i)
            if(x%i==0)
        {
            p[++num] = i;
            while(x%i==0) x/=i;
        }
        if(x > 1) p[++num] = x;
    }
    int p2[N], cnt2;
    int x2;
    int main()
    {
        scanf("%d", &x2);
        get(x2, p1, cnt1);
        int ans = INF;
        rep(i,1,cnt1)
        {
            rep(x1, x2-p1[i]+1, x2)
            {
                get(x1, p2, cnt2);
                rep(l,1,cnt2)
                {
                    if(x1-p2[l]+1 >= 3)
                        ans = min(ans, x1-p2[l]+1);
                }
            }
        }
        printf("%d
    ", ans);
    
        return 0;
    }
    View Code

    C. Producing Snow

    二分+树状数组,对于 v[i] 看它最后在哪天消耗完。 然后树状数组 区间更新,单点查询。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005;
    
    int n;
    ll  v[N], t[N], bit[N], sum[N], ans[N];
    void Add(int x, ll y) {
        for( ; x<N; x+=x&-x) bit[x] += y;
    }
    ll  Sum(int x) {
        ll  ret=0;  for( ; x; x-=x&-x) ret += bit[x];  return ret;
    }
    int main()
    {
        scanf("%d", &n);
        rep(i,1,n) scanf("%lld", &v[i]);
        rep(i,1,n) scanf("%lld", &t[i]), sum[i]=sum[i-1]+t[i];
        sum[n+1] = 1e18;
        rep(i,1,n)
        {
            int pos = upper_bound(sum+1, sum+n+2, sum[i-1]+v[i]) - sum;
            ans[pos] += v[i] - (sum[pos-1]-sum[i-1]);
            Add(i, 1),  Add(pos, -1);
            ans[i] += Sum(i)*t[i];
        }
        rep(i,1,n) printf("%lld%c", ans[i], " 
    "[i==n]);
    
        return 0;
    }
    View Code

    D. Perfect Security

    字典树

    拆分成二进制,先把第二个数组插入到 trie树里,再在 trie树里跑第一个数组中的数。有相同的位就取相同,没有就取相反的。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 300005, M = 5e6;
    
    void get(int* num, int x) {
        rep(i,0,32) num[i] = 0;
        for(int len=1; x; x>>=1, ++len) {
            if(x&1) num[len] = 1;
        }
    }
    int n, A[N], Pi;
    int num[35], tr[M][2], val[M], tot;
    void Insert(int x)
    {
        get(num, x);
        for(int u=0, i=32; i>0; --i)
        {
            if(tr[u][num[i]] == 0) tr[u][num[i]] = ++tot;
            ++val[tr[u][num[i]]];
            u = tr[u][num[i]];
        }
    }
    int query(int x)
    {
        int ret = 0;
        get(num, x);
        for(int u=0, i=32; i>0; --i)
        {
            int tmp = num[i]^1;
            if(val[tr[u][num[i]]] > 0) {
                --val[tr[u][num[i]]];
                u = tr[u][num[i]];
                ret <<= 1,  ret += num[i];
            }
            else {
                --val[tr[u][tmp]];
                u = tr[u][tmp];
                ret <<= 1,  ret += tmp;
            }
        }
        return ret;
    }
    int main()
    {
        scanf("%d", &n);
        rep(i,1,n) scanf("%d", &A[i]);
        rep(i,1,n) scanf("%d", &Pi), Insert(Pi);
        rep(i,1,n) printf("%d%c", query(A[i])^A[i], " 
    "[i==n]);
    
        return 0;
    }
    View Code
  • 相关阅读:
    11. Container With Most Water
    9. Palindrome Number
    375. 猜数字大小 II leetcode java
    leetcode 72 编辑距离 JAVA
    73. 矩阵置零 leetcode JAVA
    快速排序 JAVA实现
    63. 不同路径 II leetcode JAVA
    重写(override)与重载(overload)
    62 不同路径 leetcode JAVA
    leetcode 56 合并区间 JAVA
  • 原文地址:https://www.cnblogs.com/sbfhy/p/8549011.html
Copyright © 2011-2022 走看看