bzoj 1091 Zju2112 Dynamic Rankings - 整体二分 - 学习笔记

整体二分·屯板子

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<assert.h>
#define N 110000
#define lb(x) (x&-x)
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
struct BIT{
    int v[N],n,c,sx[N],sv[N];
    inline int init(int _n)
    { n=_n,c=0;return 0; }
    inline int update(int x,int val)
    {
        c++,sx[c]=x,sv[c]=val;
        for(;x<=n;x+=lb(x)) v[x]+=val;
        return 0;
    }
    inline int query(int x,int y)
    {
        int ans=0;
        for(;y;y-=lb(y)) ans+=v[y];
        for(x--;x;x-=lb(x)) ans-=v[x];
        return ans;
    }
    inline int clear()
    {
        for(int i=c;i>=1;i--)
            update(sx[i],-sv[i]),c--;
        return c=0;
    }
}b;
struct P{
    int kind,x,y,v,ans;
    P(int _x=0,int _y=0,int _v=0)
    { x=_x,y=_y,v=_v,kind=0,ans=0; }
    inline P operator=(const P &p)
    { kind=p.kind,x=p.x,y=p.y,v=p.v,ans=p.ans;return *this; }
}p[N],tmpL[N],tmpR[N];
int v[N],a[N],c,pc,qc,ans[N];char opt[10];
int solve(int L,int R,int s,int t)
{
    if(L>R) return 0;int mid=(s+t)>>1;
    if(s==t)
    {
        for(int i=L;i<=R;i++)
            if(p[i].kind) p[i].ans=mid;
        return 0;
    }
    int Lc=0,Rc=0,c=L-1;
//  debug(L)sp,debug(R)sp,debug(s)sp,debug(t)ln;
    for(int i=L;i<=R;i++)
        if(p[i].kind)//1:query
        {
            int s=b.query(p[i].x,p[i].y);
//          debug(i)sp,debug(p[i].x)sp,debug(p[i].y)sp,debug(p[i].v)sp,debug(s)ln;
            if(p[i].v<=s) tmpL[++Lc]=p[i];
            else p[i].v-=s,tmpR[++Rc]=p[i];
        }
        else{
//          debug(i)sp,debug(p[i].x)sp,debug(p[i].y)sp,debug(p[i].v)ln;
            if(p[i].y>mid) tmpR[++Rc]=p[i];
            else b.update(p[i].x,p[i].v),tmpL[++Lc]=p[i];
        }
//  cerr ln;
    for(int i=1;i<=Lc;i++) p[++c]=tmpL[i];
    for(int i=1;i<=Rc;i++) p[++c]=tmpR[i];
    b.clear(),solve(L,L+Lc-1,s,mid),solve(L+Lc,R,mid+1,t);
    return 0;
}
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),v[++c]=a[i],p[++pc]=P(i,a[i],1);
    for(int i=1;i<=m;i++)
    {
        scanf("%s",opt);int x,y;
        if(opt[0]=='Q') p[++pc].kind=++qc,scanf("%d%d%d",&p[pc].x,&p[pc].y,&p[pc].v);
        else scanf("%d%d",&x,&y),p[++pc]=P(x,a[x],-1),p[++pc]=P(x,a[x]=y,1),v[++c]=y;
    }
    sort(v+1,v+c+1),c=unique(v+1,v+c+1)-v-1;
    for(int i=1;i<=pc;i++)
        if(!p[i].kind) p[i].y=lower_bound(v+1,v+c+1,p[i].y)-v;
//  for(int i=1;i<=pc;i++) debug(i)sp,debug(p[i].kind)sp,debug(p[i].x)sp,debug(p[i].y)sp,debug(p[i].v)ln;
    b.init(c),solve(1,pc,1,c);
    for(int i=1;i<=pc;i++)
        if(p[i].kind) ans[p[i].kind]=v[p[i].ans];
    for(int i=1;i<=qc;i++) printf("%d\n",ans[i]);
    return 0;
}
发布了574 篇原创文章 · 获赞 25 · 访问量 10万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览