2019nc#4

题号标题已通过代码题解通过率团队的状态
A meeting 点击查看 树直径 604/2055  
B xor 点击查看 线段树维护线性基交 81/861 未通过
C sequence 点击查看 单调栈,笛卡尔树 479/2755  
D triples I 点击查看 构造 464/2974  
E triples II 点击查看 进入讨论 35/84 未通过
F merge 点击查看 splay,FHQ-TREE 4/37  
G tree 点击查看 进入讨论 2/43 未通过
H RNGs 点击查看 进入讨论 1/66 未通过
I string 点击查看 后缀数组,回文树 157/677  
J free 点击查看 分层图最短路 784/2790  
K number 点击查看 dp 859/3484  

K

题意

问一个字符串中有多少个连续子串是300的倍数

思路

O(300n)的dp即可

#include <bits/stdc++.h>

using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;



template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}

const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;

/**********showtime************/
            const int maxn = 1e5+9;
            ll dp[maxn][303];
            char str[maxn];
int main(){
            scanf("%s", str + 1);
            int n = strlen(str + 1);
//            dp[0][0] = 1;
            ll ans = 0;
            for(int i=0; i<n; i++) {
                int tp = str[i + 1] - '0';
                for(int j=0; j<300; j++) {
//                    debug(tp);
                    dp[i+1][(j*10 + tp) % 300] += dp[i][j];
                }
                dp[i+1][tp] ++;
                ans += dp[i+1][0];
            }
            printf("%lld\n", ans);
            return 0;
}
View Code

 

F merge

题意

给定一个1~n的排列,有两种操作,1)对区间 [le,mid]和[mid+1, ri] 进行一次归并排序,2)查询区间第i个位子上的值。

思路

利用fhq_tree。区间分裂操作。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include <bits/stdc++.h>

using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;



template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}

const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;

/**********showtime************/

struct fhq_treap {
    static const int N = 1e5 + 5;
    struct Node {
        int val, key, lc, rc, sz, mx;
    }tree[N];
    int rt, tot;
    inline void init() {
        rt = tot = 0;
        tree[rt].sz = tree[rt].val = tree[rt].lc = tree[rt].rc = 0;
        srand(time(0));
    }
    inline void update(int rt) {
        tree[rt].sz = tree[tree[rt].lc].sz + 1 + tree[tree[rt].rc].sz;
        tree[rt].mx = max(tree[tree[rt].lc].mx,max(tree[rt].val,tree[tree[rt].rc].mx));
    }

    void split_val(int rt, int &a, int &b, int val) {
        if(rt == 0) {a = b = 0; return ;}
        if(max(tree[rt].val , tree[tree[rt].lc].mx) <= val) {
            a = rt;
            split_val(tree[rt].rc, tree[a].rc, b, val);
        }
        else {
            b = rt;
            split_val(tree[rt].lc, a, tree[b].lc, val);
        }
        update(rt);
    }
    void split_sz(int rt, int &a, int &b, int sz) {
        if(rt == 0) {a = b = 0; return ;}
        if(tree[tree[rt].lc].sz + 1 > sz) {
            b = rt;
            split_sz(tree[rt].lc, a, tree[b].lc, sz);
        }
        else {
            a = rt;
            split_sz(tree[rt].rc, tree[a].rc, b, sz - 1 - tree[tree[rt].lc].sz);
        }
        update(rt);
    }

    void merge(int &rt, int a, int b) {
        if(a==0 || b==0) {
            rt = a+b;
            return ;
        }
        if(tree[a].key < tree[b].key) {
            rt = a;
            merge(tree[rt].rc, tree[a].rc, b);
        }
        else {
            rt = b;
            merge(tree[rt].lc, a, tree[b].lc);
        }
        update(rt);
    }

    inline int new_node(int val) {
        tree[++tot].sz = 1;
        tree[tot].val = val;
        tree[tot].lc = tree[tot].rc = 0;
        tree[tot].key = rand();
        tree[tot].mx = val;
        return tot;
    }

    void ins(int &rt, int val) {
        int x = 0, y = 0, node = new_node(val);
        merge(rt, rt, node);
    }
    void delete_node(int &rt, int val) {
        int x = 0, y = 0, z = 0;
        split_val(rt, x, y, val);
        split_val(x, x, z, val-1);
        merge(z, tree[z].lc, tree[z].rc);
        merge(x, x, z);
        merge(rt, x, y);
    }
    inline int get_kth(int rt, int k) {
        while(tree[tree[rt].lc].sz+1 != k) {
            if(tree[tree[rt].lc].sz >= k) rt = tree[rt].lc;
            else k -= tree[tree[rt].lc].sz+1, rt = tree[rt].rc;
        }
        return tree[rt].val;
    }
    int get_rnk(int &rt, int val) {
        int x = 0, y = 0;
        split_val(rt, x, y, val-1);
        int tmp = tree[x].sz+1;
        merge(rt, x, y);
        return tmp;
    }
    int get_pre(int &rt, int val) {
        int x = 0, y = 0;
        split_val(rt, x,  y, val-1);
        int tmp = get_kth(x, tree[x].sz);
        merge(rt, x, y);
        return tmp;
    }
    int get_scc(int &rt, int val) {
        int x = 0, y = 0;
        split_val(rt, x, y, val);
        int tmp = get_kth(y, 1);
        merge(rt, x, y);
        return tmp;
    }
}t;


            const int maxn = 1e5+9;
            int n,m;
            int a[maxn];
            void display(int x) {
                if(t.tree[x].lc) display(t.tree[x].lc);
                if(t.tree[x].rc) display(t.tree[x].rc);
            }
            void solve(int le, int mid ,int ri) {
                int x, y, z;
                t.split_sz(t.rt, x, z, ri);
                t.split_sz(x, x, y, mid);

                int tmp;
                int r = 0;
                while(x && y) {
                    int p = t.get_kth(x, 1);
                    int q = t.get_kth(y, 1);

                    if(p > q) swap(p, q), swap(x, y);
                    t.split_val(x, tmp, x, q);
                    t.merge(r,r, tmp);
                }
                t.merge(r, r,  x);
                t.merge(r, r,  y);
                t.merge(r, r,  z);
                t.rt = r;
            }
int main(){
            t.init();
            scanf("%d%d", &n, &m);
            for(int i=1; i<=n; i++) {
                scanf("%d", &a[i]);
                t.ins(t.rt, a[i]);
            }
            while(m--){
                int op; scanf("%d", &op);
                if(op == 2) {
                    int x;  scanf("%d", &x);
                    printf("%d\n", t.get_kth(t.rt, x));
                }
                else {
                    int le, mid, ri;
                    scanf("%d%d%d", &le, &mid, &ri);
                    solve(le, mid, ri);
                }
            }
            return 0;
}

/*
5 10
3 2 1 5 4
1 1 2 5


*/
View Code

 

 

 

posted @ 2019-07-27 23:12  ckxkexing  阅读(183)  评论(0编辑  收藏  举报