zoukankan      html  css  js  c++  java
  • COJ986 WZJ的数据结构(负十四)

    WZJ的数据结构(负十四)
    难度级别:D; 运行时间限制:6000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
    试题描述

    请你设计一个数据结构,完成以下功能:

    给定一个大小为N的整数组A,M次操作,操作分两种:

    1.1 i j k 每次询问给你i,j,k三个参数,求Ai至Aj中第k小的数。

    2.0 x v 每次操作给你x,v两个参数,将A[x]改成v。 

    输入
    第一行为两个正整数N,M。
    第二行为N个正整数Ai。
    接下来M行为操作。
    输出
    对于每个询问输出答案(保证k合法)。
    输入示例
    6 8
    1 3 2 2 5 3
    1 1 3 2
    1 1 4 2
    1 1 4 3
    1 1 4 4
    0 4 3
    1 1 4 3
    0 2 5
    1 1 4 4
    输出示例
    2
    2
    2
    3
    3
    5
    其他说明
    1<=N,M,Ai,v<=100000
    1<=i<=j<=N
    1<=k<=j-i+1
    1<=x<=N
     

    写一个二分+树状数组+Treap,挺爽的

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<ctime>
    #include<cstring>
    #include<algorithm>
    #define rep(s,t) for(int i=s;i<=t;i++)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=100010;
    const int maxnode=2000010;
    struct Node {
        Node* ch[2];
        int r,s,v;
        void maintain() {s=ch[0]->s+ch[1]->s+1;}
    }nodes[maxnode],*null=&nodes[0];
    queue<Node*> del;
    int n,A[maxn],ToT;
    Node* newnode(int v) {
        Node* o;
        if(!del.empty()) o=del.front(),del.pop();
        else o=&nodes[++ToT];
        o->ch[0]=o->ch[1]=null;
        o->s=1;o->v=v;o->r=rand();
        return o;
    }
    void remove(Node* &o) {
        del.push(o);o=null;
    }
    void rotate(Node* &o,int d) {
        Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
        o->maintain();k->maintain();o=k;
    }
    void insert(Node* &o,int v) {
        if(o==null) o=newnode(v);
        else {
            int d=v>o->v;insert(o->ch[d],v);
            if(o->ch[d]->r>o->r) rotate(o,d^1);
            else o->maintain();
        }
    }
    void remove(Node* &o,int v) {
        if(o->v==v) {
            Node* t=o;
            if(o->ch[0]==null) o=o->ch[1],remove(t);
            else if(o->ch[1]==null) o=o->ch[0],remove(t);
            else {
                int d=o->ch[0]->r>o->ch[1]->r;
                rotate(o,d);remove(o->ch[d],v);
            }
        }
        else remove(o->ch[v>o->v],v);
        if(o!=null) o->maintain();
    }
    void print(Node* o) {
        if(o==null) return;
        print(o->ch[0]);
        printf("%d ",o->v);
        print(o->ch[1]);
    }
    int query(Node* &o,int v) {
        if(o==null) return 0;
        if(v<=o->v) return query(o->ch[0],v);
        return query(o->ch[1],v)+o->ch[0]->s+1;
    }
    Node* root[maxn];
    void insert(int x,int v) {for(;x<=n;x+=x&-x) insert(root[x],v);}
    void update(int x,int v) {for(;x<=n;x+=x&-x) remove(root[x],v);}
    int query(int x,int v) {int ret=0;for(;x;x-=x&-x) ret+=query(root[x],v+1);return ret;}
    int main() {
        null->s=0;srand(time(0));
        n=read();int m=read();
        rep(1,n) root[i]=null;
        rep(1,n) insert(i,A[i]=read());
        while(m--) {
            if(read()) {
                int l=read(),r=read(),k=read();
                int L=1,R=100000,M;
                while(L<R) if(query(r,M=L+R>>1)-query(l-1,M=L+R>>1)>=k) R=M; else L=M+1;
                printf("%d
    ",L);
            }
            else {
                int x=read();update(x,A[x]);
                insert(x,A[x]=read());
            }
        }
        return 0;
    }
    View Code

    复习一下树状数组+可持久化线段树,写WA了一发真不爽

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define rep(s,t) for(int i=s;i<=t;i++)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=100010;
    const int maxnode=20000010;
    int ls[maxnode],rs[maxnode],s[maxnode],ToT;
    int n,m,A[maxn],root[maxn],c[maxn];
    void update(int& y,int x,int l,int r,int pos,int v) {
        s[y=++ToT]=s[x]+v;if(l==r) return;
        int mid=l+r>>1;ls[y]=ls[x];rs[y]=rs[x];
        if(pos<=mid) update(ls[y],ls[x],l,mid,pos,v);
        else update(rs[y],rs[x],mid+1,r,pos,v);
    }
    void update(int x,int v) {
        for(int i=x;i<=n;i+=i&-i) update(c[i],c[i],1,100000,A[x],-1);
        for(int i=x;i<=n;i+=i&-i) update(c[i],c[i],1,100000,A[x]=v,1);
    }
    int lt[maxn],rt[maxn],ltot,rtot;
    void get(int x,int tp) {
        if(!tp) {lt[ltot=1]=root[x];for(;x;x-=x&-x) if(c[x]) lt[++ltot]=c[x];}
        else {rt[rtot=1]=root[x];for(;x;x-=x&-x) if(c[x]) rt[++rtot]=c[x];}
    }
    int main() {
        n=read();m=read();
        rep(1,n) update(root[i],root[i-1],1,100000,A[i]=read(),1);
        while(m--) {
            if(!read()) {
                int x=read(),v=read();
                update(x,v);
            }
            else {
                int ql=read(),qr=read(),k=read();
                get(ql-1,0);get(qr,1);int l=1,r=100000;
                while(l<r) {
                    int mid=l+r>>1,tot=0;
                    rep(1,ltot) tot-=s[ls[lt[i]]];
                    rep(1,rtot) tot+=s[ls[rt[i]]];
                    if(tot>=k) {
                        r=mid;
                        rep(1,ltot) lt[i]=ls[lt[i]];
                        rep(1,rtot) rt[i]=ls[rt[i]];
                    }
                    else {
                        l=mid+1;k-=tot;
                        rep(1,ltot) lt[i]=rs[lt[i]];
                        rep(1,rtot) rt[i]=rs[rt[i]];
                    }
                }
                printf("%d
    ",l);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    动态生成Zip
    Net 项目构建基于Jenkins + Github + Mono 的持续集成环境
    net中使用ETW事件
    JS模板引擎
    DDD事件总线
    ASP.NET5 Beta8
    Big ball of Mud
    Jil序列化JSON
    DotNetOpenAuth实践
    centos安装wget 及配置(转)
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4602106.html
Copyright © 2011-2022 走看看