zoukankan      html  css  js  c++  java
  • LA3699

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1700

      维护一个数集,支持两个操作:

        B x:插入一个数x

        A x:查询在mod x意义下最小的数的插入时间,如果有多个输出最近的。

      x的范围是[1,500000]。操作数≤40000。

      因为x的范围比较小,我们可以分块。另lim=2500。

      对于x<lim,我们暴力维护一个数组exist[i][j],代表在mod i意义下等于j的最近位置,插入一次用O(lim)的时间更新,查询O(1)。

      对于x≥lim,我们枚举答案对于除以x的商i,易知商≤500000/lim,然后求lower_bound(x×i),更新答案。用splay实现,插入O(log(n)),查询O(log(n)×500000/lim)。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=40015,maxv=500015,lim=2500;
    struct Tsplay{
        struct Tnode{
            int n,val;Tnode *f,*c[2];
            void link(Tnode *newf,int newn){
                n=newn;f=newf;
                if (n!=2) f->c[n]=this;
            }
        }*null,*root,T[maxn];
        int tot;
        void clear(){
            tot=0;root=null=T;null->val=-1;
            null->c[0]=null->c[1]=null;
        }
        Tnode *newnode(int v){
            Tnode *cur=T+(++tot);
            cur->n=2;cur->val=v;
            cur->c[0]=cur->c[1]=cur->f=null;
            return cur;
        }
        void rotate(Tnode *x){
            Tnode *y=x->f,*z=y->f;int nx=x->n,ny=y->n;
            x->link(z,ny);x->c[!nx]->link(y,nx);y->link(x,!nx);
        }
        void splay(Tnode *x){
            while (x->n!=2){
                x->n==x->f->n?rotate(x->f):rotate(x);
                if (x->n!=2) rotate(x);
            }
            root=x;
        }
        void insert(int v){
            if (root==null){root=newnode(v);return;}
            Tnode *x=root;
            while (1){
                if (v<x->val){
                    if (x->c[0]==null){x->c[0]=newnode(v);x->c[0]->link(x,0);splay(x->c[0]);return;}
                    else x=x->c[0];
                }
                else{
                    if (x->c[1]==null){x->c[1]=newnode(v);x->c[1]->link(x,1);splay(x->c[1]);return;}
                    else x=x->c[1];
                }
            }
        }
        int lower_bound(int v){
            if (root==null) return -1;
            Tnode *x=root,*res=null;
            while (x!=null){
                if (x->val>=v){res=x;x=x->c[0];}
                else x=x->c[1];
            }
            if (res!=null) splay(res);
            return res->val;
        }
    }splay;
    int n,vis[maxv],exist[lim][lim];
    void insert(int x,int t){
        if (!vis[x]) splay.insert(x);vis[x]=t;
        for (int i=1;i<lim;++i) exist[i][x%i]=t;
    }
    void query(int x){
        if (x<lim){
            for (int i=0;i<x;++i)
                if (exist[x][i]){printf("%d
    ",exist[x][i]);return;}
            printf("-1
    ");
        }
        else{
            int v=splay.lower_bound(0),d=v;
            if (v==-1){printf("-1
    ");return;}
            for (int y,i=x;(y=splay.lower_bound(i))!=-1;i+=x)
                if (y-i<d||(y-i==d&&vis[y]>vis[v])){v=y;d=y-i;}
            printf("%d
    ",vis[v]);
        }
    }
    void solve(){
        splay.clear();int tim=0;
        memset(vis,0,sizeof(vis));
        memset(exist,0,sizeof(exist));
        for (int i=1;i<=n;++i){
            char op[5];int x;
            scanf("%s%d",op,&x);
            switch (op[0]){
                case 'B':insert(x,++tim);break;
                case 'A':query(x);break;
            }
        }
    }
    int main(){
        int cases=0;
        while (scanf("%d",&n)!=EOF&&n){
            if (++cases!=1) printf("
    ");
            printf("Case %d:
    ",cases);
            solve();
        }
        return 0;
    }
    my code
  • 相关阅读:
    java学习
    瓜娃《guava》api快速入门
    List,set,Map 的用法和区别
    css selector
    字节流与字符流区别
    jsoup的elements类
    javaio-printwriter
    map遍历的四种方法
    kafka集群和zookeeper集群的部署,kafka的java代码示例
    Ubuntu12.04安装中文字体(转)
  • 原文地址:https://www.cnblogs.com/iamCYY/p/4720159.html
Copyright © 2011-2022 走看看