[NOIP模拟] 序列操作

About:

     2017.11.06 T2

Solution:

    好气,我这道题写的权值线段树,结果维护的时候搞忘清零了,只有 20 分,加上清零就 A了,当然我是指的评测机上AC,在 OJ 上要 T 一些点,有点小气。
    我用权值线段树,在修改的时候加了一个 log2H , 但我的询问是 log2H 的,比较已经过了的代码修改是 O(H) 询问也是 O(H) ,我的算法还是被卡了。

Code :

权值线段树

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

inline int read() {
    int i = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') f = -1; ch = getchar();
    }
    while(isdigit(ch)) {
        i = (i << 3) + (i << 1) + ch - '0'; ch = getchar();
    }
    return i * f;
}

const int MAXH = 1e4 + 5;
int h[MAXH], tr[MAXH << 2], MAX, mx;

inline void update(int k) {
    tr[k] = tr[k << 1] + tr[k << 1 | 1];
}

inline void build(register int k, register int s, register int t) {
    if(s == t) return (void)(tr[k] = h[s]);
    int mid = s + t >> 1;
    build(k << 1, s, mid);
    build(k << 1 | 1, mid + 1, t);
    update(k);
}

inline int query(register int k, register int s, register int t, register int x) {
    if(s == t) return s;
    int mid = s + t >> 1;
    if(tr[k << 1 | 1] >= x) return query(k << 1 | 1, mid + 1, t, x);
    else return query(k << 1, s, mid, x - tr[k << 1 | 1]);
}

inline int querysze(register int k, register int s, register int t, register int l, register int r) {
    if(l <= s && t <= r) return tr[k];
    int mid = s + t >> 1, res = 0;
    if(l <= mid) res = querysze(k << 1, s, mid, l, r);
    if(mid < r) res += querysze(k << 1 | 1, mid + 1, t, l, r);
    return res;
}

inline void modify(register int k, register int s, register int t, register int pos, register int x) {
    if(s == t) return (void)(tr[k] += x);
    int mid = s + t >> 1;
    if(pos <= mid) modify(k << 1, s, mid, pos, x);
    else modify(k << 1 | 1, mid + 1, t, pos, x);
    update(k);
}

int main() {
    int n = read(), m = read();
    for(register int i = 1; i <= n; ++i) {
        int x = read();
        ++h[x + 1], mx = max(mx, x + 1);
    }
    int MAX = 1e4 + 2;
    build(1, 1, MAX);
    int flag = 0;
    for(register int i = 1; i <= m; ++i) {
        int x = read();
        int now = query(1, 1, MAX, x); 
        if(now == 1) {
            flag = 1;
            cout<1;
            return 0;
        }
        int sze = querysze(1, 1, MAX, now, mx);
        if(now == mx) {
            int delta = sze - x;
            if(delta) 
                modify(1, 1, MAX, now, -x), 
                modify(1, 1, MAX, now - 1, x), 
                h[now - 1] += x, h[now] -= x;
            else 
                modify(1, 1, MAX, now, -sze), 
                modify(1, 1, MAX, now - 1, sze), 
                h[now - 1] += sze, h[now] -= sze, --mx;
        }
        else {
            int delta = sze - x;
            int nowsze = h[now];
            modify(1, 1, MAX, now, -nowsze + delta), 
            modify(1, 1, MAX, now - 1, nowsze - delta),
            h[now - 1] += nowsze - delta, h[now] = delta;
            for(register int i = mx; i >= now + 1; --i) {
                if(h[i]) 
                    modify(1, 1, MAX, i, -h[i]), 
                    modify(1, 1, MAX, i - 1, h[i]);
            }
            for(int i = now + 1; i <= mx; ++i)
                if(h[i]) h[i - 1] += h[i], h[i] = 0;
            --mx;
        }
    }
    if(!flag) cout<

普通的数组,但是AC

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

inline int read() {
    int i = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') f = -1; ch = getchar();
    }
    while(isdigit(ch)) {
        i = (i << 3) + (i << 1) + ch - '0'; ch = getchar();
    }
    return i * f;
}

const int MAXH = 1e4 + 5;
int h[MAXH], tr[MAXH << 2], MAX, mx;

inline int find(int x) {
    int now = 0;
    for(int i = mx; i >= 1; --i) {
        now += h[i];
        if(now >= x) return i;
    }
}

inline int query(int x) {
    int now = 0;
    for(int i = mx; i >= x; --i) 
        now += h[i];
    return now;
}
int main() {
    int n = read(), m = read();
    for(register int i = 1; i <= n; ++i) {
        int x = read();
        ++h[x + 1], mx = max(mx, x + 1);
    }
    int MAX = mx;
    int flag = 0;
    for(register int i = 1; i <= m; ++i) {
        int x = read();
        int now = find(x); 
        if(now == 1) {
            flag = 1;
            cout<1;
            return 0;
        }
        int sze = query(now);
        if(now == mx) {
            int delta = sze - x;
            if(delta) h[now - 1] += x, h[now] -= x;
            else h[now - 1] += sze, h[now] -= sze, --mx;
        }
        else {
            int delta = sze - x;
            int nowsze = h[now];
            h[now - 1] += nowsze - delta, h[now] = delta;
            for(int i = now + 1; i <= mx; ++i)
                h[i - 1] += h[i], h[i] = 0;
            --mx;
        }
    }
    if(!flag) cout<

你可能感兴趣的:(NOIP模拟,二分,线段树,平衡树)