1. 程式人生 > >Codeforces Round #470 (Div 2) B 數學 C 二分+樹狀數組 D 字典樹

Codeforces Round #470 (Div 2) B 數學 C 二分+樹狀數組 D 字典樹

fin -i insert 數組 字典 main esp ace blog

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\n", 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], " \n"[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], " \n"[i==n]);

    return 0;
}
View Code

Codeforces Round #470 (Div 2) B 數學 C 二分+樹狀數組 D 字典樹