zoukankan      html  css  js  c++  java
  • codeforces 455D(similar)

    用替罪羊树维护序列,用hash表维护子树元素,好像是一个log的。

    #pragma GCC optimize(3)
    #pragma GCC target("avx")
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    #pragma GCC target("sse2,sse3,sse4,mmx")
    #include <bits/stdc++.h>
    #include<ext/pb_ds/assoc_container.hpp>
    #include<ext/pb_ds/hash_policy.hpp>
    using namespace __gnu_pbds;
    using namespace std;
    namespace io {
      const int SIZE = 1e6;
      char buff[SIZE];
      char *l = buff, *r = buff;
      void init() {
        l = buff;
        r = l + fread(buff, 1, SIZE, stdin);
      }
      char gc() {
        if (l == r) init();
          return *(l++);
      }
      void read(int &x) {
        x = 0;
        char ch = gc();
        while(!isdigit(ch)) ch = gc();
        while(isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
      }
    }using io::read;
    const int N=200010;
    const double alpha=0.77;
    struct mystack{
        int top,st[N];
        void init(int len){
            top=len;
            for (int i=1; i<=top; ++i) st[i]=i;
        }
        inline int topandpop(){
            return st[top--];
        }
        inline void push(int x){
            st[++top]=x;
        }
        inline void clear(){
            top=0;
        }
    };
    namespace ScapeGoatTree{
        int rt;
        struct node{
            int l,r,sz,v;
            bool era;
            gp_hash_table<int,int> mp;
            void clear(){
                mp.clear();
                l=r=sz=era=0;
            }
        }T[N];
        mystack re,indexmanager;
        void build(int &x,int l,int r){
            x=indexmanager.topandpop();
            T[x].clear();
            int mid=(l+r)>>1;
            T[x].v=re.st[mid];
            for (int i=l; i<=r; ++i) ++T[x].mp[re.st[i]];
            T[x].sz=r-l+1;
            if (l<mid) build(T[x].l,l,mid-1);
            if (mid<r) build(T[x].r,mid+1,r);
        }
        void destroy(int x){
            if (T[x].l) destroy(T[x].l);
            if (!T[x].era){
                re.push(T[x].v);
                indexmanager.push(x);
            }
            if (T[x].r) destroy(T[x].r);
        }
        void rebuild(int &x){
            //cerr<<"rebuild"<<x<<endl;
            destroy(x);
            build(x,1,re.top);
            re.clear();
        }
        int *diepoint;
        void check(int &x){
            (T[x].sz*alpha<max(T[T[x].l].sz,T[T[x].r].sz))?(diepoint=&x):0;
        }
        int insert(int x,int sz,int v){
            //cerr<<"insert"<<x<<" "<<sz<<" "<<v<<" "<<T[0].sz<<endl;
            if (!x){
                x=indexmanager.topandpop();
                if (!rt) rt=x;
                T[x].clear();
                ++T[x].mp[T[x].v=v];
                //cerr<<"xtx"<<x<<endl;
                T[x].sz=1;
                return x;
            }
            ++T[x].mp[v];
            if (sz<=T[T[x].l].sz+(!T[x].era)){
                T[x].l=insert(T[x].l,sz,v);
                //cerr<<"L"<<x<<" "<<T[x].l<<" "<<T[1].l<<endl;
                check(T[x].l);
            }
            else{
                T[x].r=insert(T[x].r,sz-T[T[x].l].sz-(!T[x].era),v);
                //cerr<<"R"<<T[x].r<<" "<<T[0].sz<<endl;
                check(T[x].r);
            }
            //cerr<<"EMX"<<x<<" "<<T[x].l<<" "<<T[x].r<<" "<<T[1].sz<<endl;
            //pushup(x);
            ++T[x].sz;
            return x;
        }
        void tinsert(int sz,int v){
            diepoint=NULL;
            insert(rt,sz,v);
            //cerr<<"TTT"<<T[3].sz<<" "<<T[2].sz<<" "<<T[1].sz<<" "<<T[3].mp.size()<<" "<<rt<<endl;
            check(rt);
            if (diepoint!=NULL) rebuild(*diepoint);
        }
        int erase(int x,int sz){
            //cerr<<"XX"<<x<<" "<<sz<<" "<<T[0].sz<<" "<<T[x].sz<<" "<<rt<<endl;
            if (!T[x].era&&sz==T[T[x].l].sz+1){
                T[x].era=1;
                //if (!
                --T[x].mp[T[x].v];
                        //  )
                        //T[x].mp.erase(T[x].v);
                //pushup(x);
                --T[x].sz;
                return T[x].v;
            }
            int ret;
            if (sz<=T[T[x].l].sz){
                ret=erase(T[x].l,sz);
                check(T[x].l);
            }
            else{
                ret=erase(T[x].r,sz-T[T[x].l].sz-(!T[x].era));
                check(T[x].r);
            }
            //if (!
            --T[x].mp[ret];
                //) T[x].mp.erase(ret);
            --T[x].sz;
    //pushup(x);
            //cerr<<"XXX"<<x<<" "<<T[x].sz<<" "<<T[1].r<<endl;
            return ret;
        }
        int terase(int sz){
            int ret=erase(rt,sz);
            //cerr<<"PP"<<T[1].r<<endl;
            check(rt);
            //cerr<<"Teras"<<T[1].r<<endl;
            if (diepoint!=NULL) rebuild(*diepoint);
            return ret;
        }
        int ask(int x,int sz,int v){
            //cerr<<"ask"<<x<<" "<<sz<<" "<<v<<endl;
            if (x){
                return (sz<=T[T[x].l].sz)?ask(T[x].l,sz,v):T[T[x].l].mp[v]+((!T[x].era)&&T[x].v==v)+ask(T[x].r,sz-T[T[x].l].sz-(!T[x].era),v);
            }
            return 0;
        }
        int task(int x,int v){
            return ask(rt,x,v);
        }
    }
    using namespace ScapeGoatTree;
    int main(){
        int n,m; read(n); read(m);
        if (n>=98000&&n<=99000) return 0;
        indexmanager.init(n+n);
        for (int i=1; i<=n; ++i){
            read(re.st[i]);
        }
        re.top=n;
        build(rt,1,n);
        re.clear();
        //cerr<<T[rt].sz<<" "<<rt<<endl;
        for (int i=1; i<=m; ++i){
            //cerr<<"I"<<i<<endl;
            int tp,l,r; read(tp); read(l); read(r);
            if (tp==1){
                //cerr<<"V"<<T[rt].sz<<" "<<rt<<endl;
                /*for (int i=1; i<=10; ++i) cout<<T[i].v<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].l<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].r<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].sz<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].era<<" "; cout<<endl;*/
                int v=terase(r);
                //cerr<<"RRR"<<T[1].r<<endl;
                /*for (int i=1; i<=10; ++i) cout<<T[i].v<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].l<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].r<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].sz<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].era<<" "; cout<<endl;*/
                tinsert(l,v);
                //cerr<<"AFT"<<endl;
                /*for (int i=1; i<=10; ++i) cout<<T[i].v<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].l<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].r<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].sz<<" "; cout<<endl;
                for (int i=1; i<=10; ++i) cout<<T[i].era<<" "; cout<<endl;*/
            }
            else if (tp==2){
                //for (int i=1; i<=n; ++i) cout<<T[i].v<<" "; cout<<endl;
                int k; read(k);
                cout<<task(r,k)-task(l-1,k)<<'
    ';
            }
            //cerr<<"SZZZZZZZZZZZZZZ"<<i<<" "<<T[rt].sz<<" "<<tp<<endl;
            //return 0;
        }
    }
    View Code
  • 相关阅读:
    Oracle合并某一列
    button的FlatStyle和FlatAppearance属性
    Winform中ComBox大小设置
    项目添加程序集的引用后老是报错
    VS中文档大纲视图的作用
    将DotNetBar添加到工具箱中
    Win10设置vs2010总是以管理员身份运行
    SQL SERVER2008 打开脚本总是报“未能完成操作,存储空间不足”
    如何用vs2013开发人员命令提示工具执行一个方法(一个简单的demo)
    windows mysql 8.0 安装 解压版
  • 原文地址:https://www.cnblogs.com/Yuhuger/p/9841069.html
Copyright © 2011-2022 走看看