2017年3月31日 星期五

[TIOJ] 1840 . Coding Days コーディングデイス [動態第K大] [整體二分]

http://tioj.ck.tp.edu.tw/problems/1840

法一:

BIT + PST  (Binary Indexed Tree + Persistent Segment Tree)
BIT + 可持久化線段樹
樹狀數組 + 主席樹

#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;

const int MAX_N = 6e4 + 6;
const int MAX_P = 4e6 + 6;
const int MAX_M = 1e4 + 6;

struct Node {
    static Node mem[MAX_P];
    Node *lc,*rc;
    int sum;
    Node() {
        lc=rc=NULL;
        sum=0;
    }
    void pull() {
        sum = lc->sum + rc->sum;
    }
} Node::mem[MAX_P],*ptr=Node::mem;

Node *Build(int L,int R) {
    Node* node=new(ptr++)Node();
    if (L==R) {
        return node;
    }
    int mid=(L+R)>>1;
    node->lc=Build(L,mid);
    node->rc=Build(mid+1,R);
    return node;
}

Node* getNode(Node* old) {
    Node* node = new(ptr++)Node();
    node->lc=old->lc;
    node->rc=old->rc;
    node->sum=old->sum;
    return node;
}

void modify(Node* node,Node* old,int L,int R,int pos,int val) {
    if (L==R) {
        node->sum += val;
        return;
    }
    int mid=(L+R)>>1;
    if (pos <= mid) {
        node->lc=getNode(old->lc);
        modify(node->lc,old->lc,L,mid,pos,val);
    }
    else {
        node->rc=getNode(old->rc);
        modify(node->rc,old->rc,mid+1,R,pos,val);
    }
    node->pull();
    return;
}

struct Q {
    int type;
    int a,b,c;
    void input() {
        scanf("%d",&type);
        if (type==1) scanf("%d %d %d",&a,&b,&c);
        else scanf("%d %d",&a,&b);
    }
} q[MAX_M];

int a[MAX_N];

Node* root[MAX_N];
Node* bit_root[MAX_N];

int query(Node* L_1tree,Node* Rtree,vector<Node*> bitL_1,vector<Node*> bitR,int L,int R,int k) {
    if (L==R) {
        return L;
    }
    int sumr = Rtree->lc->sum;
    int suml = L_1tree->lc->sum;
    for (auto i:bitL_1) {
        suml += i->lc->sum;
    }
    for (auto i:bitR) {
        sumr += i->lc->sum;
    }
    int mid=(L+R)>>1;
    if (k <= sumr-suml) {
        for (Node* &i:bitL_1) {
            i = i->lc;
        }
        for (Node* &i:bitR) {
            i = i->lc;
        }
        return query(L_1tree->lc,Rtree->lc,bitL_1,bitR,L,mid,k);
    }
    else {
        for (Node* &i:bitL_1) {
            i = i->rc;
        }
        for (Node* &i:bitR) {
            i = i->rc;
        }
        return query(L_1tree->rc,Rtree->rc,bitL_1,bitR,mid+1,R,k-sumr+suml);
    }
}

int main () {
    int T;
    scanf("%d",&T);
    while (T--) {
        ptr = Node::mem;
        int n,m;
        scanf("%d %d",&n,&m);
        vector<int> v;
        for (int i=1;n>=i;i++) {
            scanf("%d",&a[i]);
            v.push_back(a[i]);
        }
        for (int i=1;m>=i;i++) {
            q[i].input();
            if (q[i].type == 2) v.push_back(q[i].b);
        }
        sort(v.begin(),v.end());
        v.resize(unique(v.begin(),v.end()) - v.begin());
        for (int i=1;n>=i;i++) {
            a[i]=lower_bound(v.begin(),v.end(),a[i]) - v.begin() +1;
        }
        for (int i=1;m>=i;i++) {
            if (q[i].type == 2) q[i].b = lower_bound(v.begin(),v.end(),q[i].b) - v.begin() + 1;
        }
        int nn=v.size();
        root[0] = Build(1,nn);
        for (int i=1;n>=i;i++) {
            root[i] = getNode(root[i-1]);
            modify(root[i],root[i-1],1,nn,a[i],1);
            bit_root[i] = getNode(root[0]);
        }
        for (int j=1;m>=j;j++) {
            if (q[j].type == 3) {
                puts("7122");
            }
            else if (q[j].type==1) {
                int L=q[j].a;
                int R=q[j].b;
                int k=q[j].c;
                vector<Node*> bitL_1,bitR;
                for (int i=R;i>0;i-=(i&(-i))) {
                    bitR.push_back(bit_root[i]);
                }
                for (int i=L-1;i>0;i-=(i&(-i))) {
                    bitL_1.push_back(bit_root[i]);
                }
                int ret=query(root[L-1],root[R],bitL_1,bitR,1,nn,k);
                printf("%d\n",v[ret-1]);
            }
            else if (q[j].type==2) {
                int pos=q[j].a;  //pos
                int val=q[j].b;  //val
                int ori=a[pos];
                for (int i=pos;n>=i;i+=(i&(-i))) {
                    modify(bit_root[i],bit_root[i],1,nn,ori,-1);
                }
                for (int i=pos;n>=i;i+=(i&(-i))) {
                    modify(bit_root[i],bit_root[i],1,nn,val,1);
                }
                a[pos] = q[j].b;
            }
        }
    }
}

法二:

整體二分

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cassert>
using namespace std;

#define SZ(x) ((int)(x).size())

const int N = 2e5 + 6;

int a[N];

struct Event {
    int time,pos,val,flag;
    Event(int _time,int _pos,int _val,int _flag):time(_time),pos(_pos),val(_val),flag(_flag){}
};

int ans[N];

struct Query {
    int L,R,k,time,id;
    Query(int _L,int _R,int _k,int _time,int _id):L(_L),R(_R),k(_k),time(_time),id(_id){}
};

struct BIT {
    int n;
    int p[N];
    void init(int n) {
        this->n = n;
        for (int i=0;n>=i;++i) p[i]=0;
    }
    void add(int pos,int val) {
        for (int i=pos;n>=i;i+=i&(-i)) {
            p[i] += val;
        }
    }
    int qry(int pos) {
        int ret=0;
        for (int i=pos;i>=1;i-=i&(-i)) {
            ret += p[i];
        }
        return ret;
    }
    int query(int L,int R) {
        return qry(R) - qry(L-1);
    }
} bit;

void split_event(int mid,vector<Event>& e,vector<Event>& le,vector<Event>& re) {
    for (Event ee:e) {
        if (ee.val <= mid) le.push_back(ee);
        else re.push_back(ee);
    }
    vector<Event> ().swap(e);
}

void totBS(int L,int R,vector<Query> q,vector<Event> e) {
    if (L==R) {
        for (Query qq:q) {
            ans[qq.id] = L;
        }
        return;
    }
    int mid=(L+R)>>1;
    vector<Event> le,re;
    split_event(mid,e,le,re);
    vector<Query> lq,rq;
    int eid=-1;
    for (int i=0;SZ(q)>i;i++) {
        Query &qq=q[i];
        while (eid+1 < SZ(le) && le[eid+1].time <= qq.time) {
            bit.add(le[eid+1].pos,le[eid+1].flag);
            eid++;
        }
        int ret=bit.query(qq.L,qq.R);
        if (ret < qq.k) {
            qq.k -= ret;
            rq.push_back(qq);
        }
        else {
            lq.push_back(qq);
        }
    }
    while (eid >= 0) {
        bit.add(le[eid].pos,-le[eid].flag);
        eid--;
    }
    vector<Query> ().swap(q);
    totBS(L,mid,lq,le);
    totBS(mid+1,R,rq,re);
}

int main () {
    int T;
    scanf("%d",&T);
    while (T--) {
        int n,m;
        scanf("%d %d",&n,&m);
        vector<Query> q;
        vector<Event> e;
        vector<int> v;
        for (int i=1;n>=i;++i) {
            scanf("%d",&a[i]);
            e.push_back(Event(0,i,a[i],1));
            v.push_back(a[i]);
        }
        for (int i=1;m>=i;++i) {
            ans[i] = 0;
            int type;
            scanf("%d",&type);
            if (type == 2) {
                //change
                int pos,val;
                scanf("%d %d",&pos,&val);
                v.push_back(val);
                e.push_back(Event(i,pos,a[pos],-1));
                e.push_back(Event(i,pos,val,1));
                a[pos] = val;
            }
            else if (type == 1) {
                int L,R,k;
                scanf("%d %d %d",&L,&R,&k);
                q.push_back(Query(L,R,k,i,i));
            }
            else if (type == 3) {
                int pos,val;
                scanf("%d %d",&pos,&val);
                ans[i] = -2;
            }
        }
        sort(v.begin(),v.end());
        v.resize(unique(v.begin(),v.end()) - v.begin());
        for (Event &ee:e) {
            ee.val = lower_bound(v.begin(),v.end(),ee.val) - v.begin() + 1;
        }
        bit.init(n);
        totBS(1,SZ(v),q,e);
        for (int i=1;m>=i;i++) {
            if (ans[i] != 0) {
                if (ans[i] != -2) printf("%d\n",v[ans[i]-1]);
                else puts("7122");
            }
        }
    }
}


沒有留言:

張貼留言