• 整体二分--BZOJ1901: Zju2112 Dynamic Rankings


    n<=10000个数有m<=10000个操作,1、询问一个区间的第k小的数;2、单点修改。

    带修主席树。

    整体二分。

    整体二分的必要条件:

    这里写图片描述

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 //#include<assert.h>
     5 #include<algorithm>
     6 //#include<iostream>
     7 using namespace std;
     8 
     9 int n,m;
    10 #define maxn 30011
    11 const int inf=0x3f3f3f3f;
    12 struct Ope
    13 {
    14     int x,y,z,id,type;
    15     //type=1: 询问区间[x,y]第z大,询问编号id
    16     //type=0:把位置x的数修改为y,增加:z=1,删除:z=-1
    17 }q[maxn],al[maxn],ar[maxn];int len;
    18 int ans[maxn];
    19 
    20 struct BIT
    21 {
    22     int a[maxn];
    23     void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;}
    24     int query(int x) {int ans=0; for (;x;x-=x&-x) ans+=a[x]; return ans;}
    25 }t;
    26 
    27 void solve(int L,int R,int ql,int qr)
    28 {
    29     if (L>R || ql>qr) return;
    30     if (L==R)
    31     {
    32         for (int i=ql;i<=qr;i++) if (q[i].type) ans[q[i].id]=L;
    33         return;
    34     }
    35     int mid=(L+R)>>1,lql=0,lqr=0;
    36     for (int i=ql;i<=qr;i++)
    37     {
    38         if (q[i].type)
    39         {
    40             int tmp=t.query(q[i].y)-t.query(q[i].x-1);
    41             if (tmp>=q[i].z) al[++lql]=q[i];
    42             else
    43             {
    44                 q[i].z-=tmp;
    45                 ar[++lqr]=q[i];
    46             }
    47         }
    48         else
    49         {
    50             if (q[i].y<=mid)
    51             {
    52                 t.add(q[i].x,q[i].z);
    53                 al[++lql]=q[i];
    54             }
    55             else ar[++lqr]=q[i];
    56         }
    57     }
    58     for (int i=1;i<=lql;i++) if (al[i].type==0) t.add(al[i].x,-al[i].z);
    59     for (int i=1,j=ql;i<=lql;i++,j++) q[j]=al[i];
    60     for (int i=1,j=ql+lql;i<=lqr;i++,j++) q[j]=ar[i];
    61     solve(L,mid,ql,ql+lql-1);
    62     solve(mid+1,R,ql+lql,qr);
    63 }
    64 
    65 int a[maxn];
    66 int main()
    67 {
    68     scanf("%d%d",&n,&m);
    69     for (int i=1;i<=n;i++) scanf("%d",&q[i].y),a[i]=q[i].y,q[i].x=i,q[i].z=1,q[i].type=0;
    70     char s[5];
    71     int cntq=0;
    72     for (int i=1,j=n+1;i<=m;i++,j++)
    73     {
    74         scanf("%s",s);
    75         if (s[0]=='Q') scanf("%d%d%d",&q[j].x,&q[j].y,&q[j].z),q[j].id=++cntq,q[j].type=1;
    76         else scanf("%d%d",&q[j].x,&q[j].y),q[j].z=1,q[j].type=0,
    77         q[j+1]=(Ope){q[j].x,a[q[j].x],-1,0,0},a[q[j].x]=q[j].y,j++;
    78         if (i==m) len=j;
    79     }
    80     solve(0,inf,1,len);
    81     for (int i=1;i<=cntq;i++) printf("%d
    ",ans[i]);
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    【方法1】删除Map中Value反复的记录,而且仅仅保留Key最小的那条记录
    hdu3415 Max Sum of Max-K-sub-sequence 单调队列
    HBase总结(十八)Hbase rowkey设计一
    Makefile生成器,使用C++和Boost实现
    quartz cron表达式在线生成
    NS3网络仿真(6): 总线型网络
    连载:面向对象葵花宝典:思想、技巧与实践(35)
    zoj 2921 Stock(贪心)
    11g RAC 加节点 之 手动加入vip 资源
    [Unity3D]Unity+Android交互教程——让手机&quot;动&quot;起来
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8231903.html
Copyright © 2020-2023  润新知