zoukankan      html  css  js  c++  java
  • luogu2617 Dynamic Rankings

    题目描述

    题解:

    修改=删除+插入。

    具体实现时保证先删除后插入。

    就是对于某一位状态为插入->删除->插入->删除->……->插入。

    而不是插入->插入->删除->……->插入->删除。

    不然这个无脑错误会让普通线段树挂掉的。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100050
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,m,tot,cnt,vl[N],to[3*N],mx,ans[N],qcnt;
    char ch[2];
    struct node
    {
        int opt;//0 in 1 out 2 query
        int l,r,k;
        int x,id;
    }p[3*N],tmpl[3*N],tmpr[3*N];
    struct Pair
    {
        int x,id;
        Pair(){}
        Pair(int x,int i):x(x),id(i){}
    }ar[3*N];
    bool cmp(Pair p1,Pair p2)
    {
        return p1.x<p2.x;
    }
    struct segtree
    {
        int siz[N*12],vl[N*12],tag[N*12];
        bool rec[N*12];
        void add(int u,int d)
        {
            tag[u]+=d;
            vl[u]+=d*siz[u];
        }
        void rece(int u)
        {
            vl[u]=tag[u] = 0;
            rec[u] = 1;
        }
        void pushdown(int u)
        {
            if(rec[u])
            {
                rece(u<<1);
                rece(u<<1|1);
                rec[u] = 0;
            }
            if(tag[u])
            {
                add(u<<1,tag[u]);
                add(u<<1|1,tag[u]);
                tag[u]=0;
            }
        }
        void update(int u)
        {
            vl[u] = vl[u<<1]+vl[u<<1|1];
        }
        void build(int l,int r,int u)
        {
            siz[u] = r-l+1;
            if(l==r)return ;
            int mid = (l+r)>>1;
            build(l,mid,u<<1);
            build(mid+1,r,u<<1|1);
        }
        void insert(int l,int r,int u,int qx,int d)
        {
            if(l==r)
            {
                add(u,d);
                return ;
            }
            pushdown(u);
            int mid = (l+r)>>1;
            if(qx<=mid)insert(l,mid,u<<1,qx,d);
            else insert(mid+1,r,u<<1|1,qx,d);
            update(u);
        }
        int query(int l,int r,int u,int ql,int qr)
        {
            if(l==ql&&r==qr)return vl[u];
            pushdown(u);
            int mid = (l+r)>>1;
            if(qr<=mid)return query(l,mid,u<<1,ql,qr);
            else if(ql>mid)return query(mid+1,r,u<<1|1,ql,qr);
            else return query(l,mid,u<<1,ql,mid)+query(mid+1,r,u<<1|1,mid+1,qr);
        }
    }tr;
    void divi(int l,int r,int beg,int ens)
    {
        if(beg>ens)return ;
        if(l==r)
        {
            for(int i=beg;i<=ens;i++)
                if(p[i].opt==2)ans[p[i].id] = to[l];
            return ;
        }
        int mid = (l+r)>>1;
        int lt = 0,rt = 0;
        bool l1=0,r1=0;
        tr.rece(1);
        for(int i=beg;i<=ens;i++)
        {
            if(!p[i].opt)
            {
                if(p[i].x<=mid)
                {
                    tr.insert(1,mx,1,p[i].id,1);
                    tmpl[++lt] = p[i];
                }else tmpr[++rt] = p[i];
            }else if(p[i].opt==1)
            {
                if(p[i].x<=mid)
                {
                    tr.insert(1,mx,1,p[i].id,-1);
                    tmpl[++lt] = p[i];
                }else tmpr[++rt] = p[i];
            }else
            {
                int now = tr.query(1,mx,1,p[i].l,p[i].r);
                if(now<p[i].k)
                {
                    p[i].k-=now;
                    r1=1;
                    tmpr[++rt] = p[i];
                }else
                {
                    l1=1;
                    tmpl[++lt] = p[i];
                }
            }
        }
        for(int i=beg;i<=beg+lt-1;i++)p[i] = tmpl[i-beg+1];
        for(int i=beg+lt;i<=ens;i++)p[i] = tmpr[i-beg-lt+1];
        if(l1)divi(l,mid,beg,beg+lt-1);
        if(r1)divi(mid+1,r,beg+lt,ens);
    }
    int main()
    {
        n = tot = rd(),m = rd();
        for(int i=1;i<=n;i++)
        {
            p[i].x = vl[i] = rd(),p[i].id = i;
            ar[++cnt] = Pair(p[i].x,i);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%s",ch);
            if(ch[0]=='C')
            {
                tot++;
                p[tot].opt = 0;
                p[tot].id = rd();
                p[tot].x = rd();
                ar[++cnt] = Pair(p[tot].x,tot);
                tot++;
                p[tot].opt = 1;
                p[tot].id = p[tot-1].id;
                p[tot].x = vl[p[tot].id];
                ar[++cnt] = Pair(p[tot].x,tot);
                vl[p[tot].id] = p[tot-1].x;
            }else
            {
                tot++;
                p[tot].opt = 2;
                p[tot].l = rd();
                p[tot].r = rd();
                p[tot].k = rd();
                p[tot].id = ++qcnt;
            }
        }
        sort(ar+1,ar+1+cnt,cmp);
        for(int las=-1,i=1;i<=cnt;i++)
        {
            if(las!=ar[i].x)
            {
                las = ar[i].x;
                to[++mx] = las;
            }
            p[ar[i].id].x = mx;
        }
        tr.build(1,mx,1);
        divi(1,mx,1,tot);
        for(int i=1;i<=qcnt;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    js-artDialog文档说明
    T-SQL数据库函数
    强大的Jquery对象选择器
    学习正则表达式
    经典正则
    其他常用的正则表达式
    celery的使用
    django中间件
    AJAX
    Django Form表单组件
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10201432.html
Copyright © 2011-2022 走看看