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
原文地址:https://www.cnblogs.com/sbfhy/p/8549011.html