• bzoj3110: [Zjoi2013]K大数查询


    整体二分加深理解~

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    
    int n;
    struct trnode
    {
        int l,r,lc,rc;LL c,lazy;
    }tr[110000];int trlen;
    void bt(int l,int r)
    {
        int now=++trlen;
        tr[now].l=l;tr[now].r=r;
        tr[now].lc=tr[now].rc=-1;
        tr[now].c=0;tr[now].lazy=0;
        if(l<r)
        {
            int mid=(l+r)/2;
            tr[now].lc=trlen+1;bt(l,mid);
            tr[now].rc=trlen+1;bt(mid+1,r);
        }
    }
    void change(LL now,int l,int r,LL k)
    {
        if(tr[now].l==l&&tr[now].r==r)
        {
            tr[now].c+=(r-l+1)*k;
            tr[now].lazy+=k;
            return ;
        }
        
        int mid=(tr[now].l+tr[now].r)/2;
        int lc=tr[now].lc,rc=tr[now].rc;
        
        if(tr[now].lazy!=0)
        {
            tr[lc].c+=(tr[lc].r-tr[lc].l+1)*tr[now].lazy;
            tr[rc].c+=(tr[rc].r-tr[rc].l+1)*tr[now].lazy;
            tr[lc].lazy+=tr[now].lazy;
            tr[rc].lazy+=tr[now].lazy;
            tr[now].lazy=0;
        }
        
             if(r<=mid)  change(lc,l,r,k);
        else if(mid+1<=l)change(rc,l,r,k);
        else change(lc,l,mid,k), change(rc,mid+1,r,k);
        
        tr[now].c=tr[lc].c+tr[rc].c;
    }
    LL getsum(int now,int l,int r)
    {
        if(l>r)return 0;
        if(tr[now].l==l&&tr[now].r==r)return tr[now].c;
        
        int mid=(tr[now].l+tr[now].r)/2;
        int lc=tr[now].lc,rc=tr[now].rc;
        
        if(tr[now].lazy!=0)
        {
            tr[lc].c+=(tr[lc].r-tr[lc].l+1)*tr[now].lazy;
            tr[rc].c+=(tr[rc].r-tr[rc].l+1)*tr[now].lazy;
            tr[lc].lazy+=tr[now].lazy;
            tr[rc].lazy+=tr[now].lazy;
            tr[now].lazy=0;
        }
        
             if(r<=mid)  return getsum(lc,l,r);
        else if(mid+1<=l)return getsum(rc,l,r);
        else return getsum(lc,l,mid)+getsum(rc,mid+1,r);
    }
    
    //------------seg_tree----------------------
    
    struct node
    {
        int t,x,y,k;
    }q[51000],lq[51000],rq[51000];
    int as[51000];
    void solve(LL l,LL r,int st,int ed)
    {
        if(st>ed)return ;
        if(l==r)
        {
            for(int i=st;i<=ed;i++)
                if(q[i].t>0)as[q[i].t]=l;
                return ;
        }
        
        LL mid=(l+r)/2,lt=0,rt=0;
        for(int i=st;i<=ed;i++)
        {
            if(q[i].t==0)
            {
                if(q[i].k<=mid)lq[++lt]=q[i];
                else
                {
                    change(1,q[i].x,q[i].y,1);
                    rq[++rt]=q[i];
                }
            }
            else
            {
                LL d=getsum(1,q[i].x,n)-getsum(1,q[i].y+1,n);
                if(d<q[i].k)
                {
                    q[i].k-=d;
                    lq[++lt]=q[i];
                }
                else rq[++rt]=q[i];
            }
        }
        
        for(int i=ed;i>=st;i--)
            if(q[i].t==0&&q[i].k>mid)change(1,q[i].x,q[i].y,-1);
            
        for(int i=1;i<=lt;i++)q[st+i-1]=lq[i];
        for(int i=1;i<=rt;i++)q[st+lt+i-1]=rq[i];
        solve(l,mid,st,st+lt-1);
        solve(mid+1,r,st+lt,ed);
    }
    
    char ss[10];
    int main()
    {
        int Q,m=0,op;
        scanf("%d%d",&n,&Q);
        for(int i=1;i<=Q;i++)
        {
            scanf("%d%d%d%d",&op,&q[i].x,&q[i].y,&q[i].k);
            if(op==1)q[i].t=0;
            else q[i].t=++m;
        }
        
        trlen=0;bt(1,n);
        solve(0,(1LL<<33),1,Q);
        for(int i=1;i<=m;i++)printf("%d
    ",as[i]);
        return 0;
    }
  • 相关阅读:
    with
    网编
    选课新系统大作业
    网络编程

    知识点
    Python
    学生选课大作业
    理解position与anchorPoint[转]
    毛玻璃效果的简单使用
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9441016.html
Copyright © 2020-2023  润新知