zoukankan      html  css  js  c++  java
  • BZOJ 3110 [Zjoi2013]K大数查询 ——整体二分

    【题目分析】

        整体二分显而易见。

        自己YY了一下用树状数组区间修改,区间查询的操作。

        又因为一个字母调了一下午。

        貌似树状数组并不需要清空,可以用一个指针来维护,可以少一个log

        懒得写了。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
      
    using namespace std;
      
    #define maxn 50005
    #define inf 0x3f3f3f3f
    #define ll long long 
      
    ll n,m,cnt=0,tot=0;
      
    struct Bit_Tree{
        ll a[maxn],b[maxn];
        void add(ll x,ll y,ll z)
        {
    //      cout<<"Add "<<x<<" "<<y<<" "<<z<<endl;
            for (ll i=x;i<=n;i+=i&(-i)) b[i]+=z;
            for (ll i=y+1;i<=n;i+=i&(-i)) b[i]-=z;
            for (ll i=x;i<=n;i+=i&(-i)) a[i]+=(n-x)*z;
            for (ll i=y+1;i<=n;i+=i&(-i)) a[i]-=(n-y-1)*z;
        }
        void init()
        {
            memset(a,0,sizeof a);
            memset(b,0,sizeof b);
        }
        ll getsum(ll x)
        {
            ll ret=0,tmp=0;
            for (ll i=x;i;i-=i&(-i)) ret+=a[i],tmp+=b[i];
            return ret-(n-x-1)*tmp;
        }
        ll get(ll x,ll y)
        {
            return getsum(y)-getsum(x-1);
        }
    }t;
      
    struct data{
        ll opt,id;
        ll x,y,z;
    }q[maxn<<1],q1[maxn<<1],q2[maxn<<1];
      
    ll ans[maxn<<1],tag[maxn<<1];
      
    void solve(ll ql,ll qr,ll l,ll r)
    {
    //  cout<<"solve"<<ql<<" "<<qr<<" "<<l<<" "<<r<<endl;
    //  cout<<"In Que"<<endl;
        if (ql>qr) return;
        if (l==r)
        {
            for (ll i=ql;i<=qr;++i) ans[q[i].id]=l; 
            return ; 
        }
        ll mid=l+r>>1,p1=0,p2=0,cnt=0;
    //    cout<<"Mid is "<<mid<<endl;
        for (ll i=ql;i<=qr;++i)
        {
    //      cout<<q[i].opt<<" "<<q[i].x<<" "<<q[i].y<<" "<<q[i].z<<" "<<endl;
            if (q[i].opt==1)
            {
                if (q[i].z<=mid)
                {
                    t.add(q[i].x,q[i].y,1);
                    cnt+=q[i].y-q[i].x+1;
                    q1[++p1]=q[i];
                }
                else q2[++p2]=q[i];
            }
            else
            {
                ll tmp=t.get(q[i].x,q[i].y);
    //            cout<<"Tmp is "<<tmp<<endl;
                if (q[i].z<=tmp) q1[++p1]=q[i];
                else q[i].z-=tmp,q2[++p2]=q[i];
            }
        }
        for (ll i=1;i<=p1;++i)
        {
            if (q1[i].opt==1) t.add(q1[i].x,q1[i].y,-1);
            q[ql+i-1]=q1[i];
        }
        for (ll i=1;i<=p2;++i) q[ql+p1+i-1]=q2[i];
        solve(ql,ql+p1-1,l,mid);
        solve(ql+p1,qr,mid+1,r);
    }
      
    int main()
    {
    //  freopen("in.txt","r",stdin);
    //  freopen("wa.txt","w",stdout);
        scanf("%lld",&n);
        n=maxn-1;
        scanf("%lld",&m);
        cnt=m;
        for (ll i=1;i<=m;++i)
        {
            scanf("%lld%lld%lld%lld",&q[i].opt,&q[i].x,&q[i].y,&q[i].z);
            q[i].id=i;
            if (q[i].opt==1) t.add(q[i].x,q[i].y,1);
            if (q[i].opt==2)
            {
                tag[i]=1;
                tot=t.get(q[i].x,q[i].y);
                q[i].z=tot-q[i].z+1;
            }
        }
        for (ll i=1;i<=m;++i)
            if (q[i].opt==1)
                t.add(q[i].x,q[i].y,-1);
        solve(1,cnt,-inf,inf);
        for (ll i=1;i<=m;++i)
            if (tag[i])
                printf("%lld
    ",ans[i]);
    }
    

      

  • 相关阅读:
    bootstrap多选框
    window.open()总结
    sql游标及模仿游标操作
    表变量及临时表数据批量插入和更新 写法
    表变量类型的创建及使用
    事物及exec
    [NOI2017]蚯蚓排队
    [NOI2017]游戏
    [NOI2017]蔬菜
    luogu P4194 矩阵
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6227804.html
Copyright © 2011-2022 走看看