zoukankan      html  css  js  c++  java
  • 【BZOJ1901】Dynamic Rankings [整体二分]

    Dynamic Rankings

    Time Limit: 10 Sec  Memory Limit: 128 MB
    [Submit][Status][Discuss]

    Description

      给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。

    Input

      第一行有两个正整数
      分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n]。
      接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。
      Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。
      C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。

    Output

      对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

    Sample Input

      5 3
      3 2 1 4 7
      Q 1 4 3
      C 2 6
      Q 2 5 3

    Sample Output

      3
      6

    HINT

      m,n≤10000 , 0≤ai≤1e9。

    Main idea

      询问区间中第k小的数是多少,需要支持单点修改点的权值。

    Solution

      我们看到这道题,发现对于一个询问应该是可以二分查找答案的,那么我们从整体二分的角度来思考。

      我们发现,如果没有修改的话,显然很简单,直接整体二分将所有询问一起操作即可。

      但是我们有操作,那应该怎么办呢?

      我们对于每一次修改,记录一下原来的值,简单来说,就是对于每一次操作,记录一下若opt=1,则表示这个点在这个状态的值;若opt=3,则表示这是一个询问

      我们对于修改来说,新增一个opt=2表示在修改之前的值。也就是说,我们在执行一个区间的操作时,如果发现一个opt=2,那么之前一定有一个一样的值的opt为1,并且其已经对答案造成影响,现在那个元素已经被修改了,就要相应地减去它之前对答案的影响,这样就完成了修改。

      然后我们整体二分权值,像静态查询kth那样修改一下即可。思路一气呵成 (≧▽≦)/

    Code

      1 #include<iostream>    
      2 #include<string>    
      3 #include<algorithm>    
      4 #include<cstdio>    
      5 #include<cstring>    
      6 #include<cstdlib>    
      7 #include<cmath>    
      8 #include<map>  
      9 using namespace std;  
     10   
     11 const int ONE=30005;
     12 const int INF=1e9+1;
     13 
     14 int n,m;
     15 int x,y,k;
     16 char ch[3];
     17 int cnt,Num;
     18 int a[ONE],record[ONE];
     19 int Ans[ONE];
     20 
     21 struct power
     22 {
     23         int opt,cnt;
     24         int l,r,k;
     25         int pos,value;
     26         int cur;
     27 }oper[ONE],qL[ONE],qR[ONE];
     28 
     29 int get()
     30 {    
     31         int res=1,Q=1;char c;    
     32         while( (c=getchar())<48 || c>57 ) 
     33         if(c=='-')Q=-1; 
     34         res=c-48;     
     35         while( (c=getchar())>=48 && c<=57 )    
     36         res=res*10+c-48;    
     37         return res*Q;    
     38 }
     39 
     40 namespace Bit
     41 {
     42         struct power
     43         {
     44             int value;
     45         }Node[ONE];
     46         
     47         int lowbit(int i)
     48         {
     49             return i&-i;
     50         }
     51         
     52         void Update(int R,int x)
     53         {
     54             for(int i=R;i<=n;i+=lowbit(i))
     55                 Node[i].value+=x;
     56         }
     57         
     58         int Query(int R)
     59         {
     60             int res=0;
     61             for(int i=R;i>=1;i-=lowbit(i))
     62                 res+=Node[i].value;
     63             return res;
     64         }
     65 }
     66 
     67 void Solve(int l,int r,int L,int R)
     68 {
     69         if(l>r) return;
     70         if(L==R)
     71         {
     72             for(int i=l;i<=r;i++)
     73             if(oper[i].opt==3)
     74                 Ans[oper[i].cnt] = L;
     75             return;
     76         }
     77         
     78         int M=(L+R)>>1;    
     79         for(int i=l;i<=r;i++)
     80         {
     81             if(oper[i].opt==1 && oper[i].value<=M)
     82                 Bit::Update(oper[i].pos,1); 
     83             if(oper[i].opt==2 && oper[i].value<=M)
     84                 Bit::Update(oper[i].pos,-1);
     85             if(oper[i].opt==3)
     86                 record[i]=Bit::Query(oper[i].r) - Bit::Query(oper[i].l-1);
     87         }
     88         
     89         for(int i=l;i<=r;i++)
     90         {
     91             if(oper[i].opt==1 && oper[i].value<=M)
     92                 Bit::Update(oper[i].pos,-1); 
     93             if(oper[i].opt==2 && oper[i].value<=M)
     94                 Bit::Update(oper[i].pos,1);
     95         }
     96         
     97         int l_num=0,r_num=0;
     98         for(int i=l;i<=r;i++)
     99         {
    100             if(oper[i].opt!=3)
    101             {
    102                 if(oper[i].value <= M)
    103                     qL[++l_num]=oper[i];
    104                 else
    105                     qR[++r_num]=oper[i];
    106             }
    107             else
    108             {
    109                 if(oper[i].cur + record[i] >= oper[i].k)
    110                     qL[++l_num]=oper[i];
    111                 else
    112                 {
    113                     qR[++r_num]=oper[i];
    114                     qR[r_num].cur+=record[i];
    115                 }
    116             }
    117         }
    118         
    119         int t=l;
    120         for(int i=1;i<=l_num;i++) oper[t++]=qL[i];
    121         for(int i=1;i<=r_num;i++) oper[t++]=qR[i];
    122         
    123         
    124         Solve(l,l+l_num-1,L,M);
    125         Solve(l+l_num,r,M+1,R);
    126 } 
    127 
    128 int main()
    129 {
    130         n=get();    m=get();
    131         for(int i=1;i<=n;i++)
    132         {
    133             a[i]=get();
    134             oper[++cnt].opt=1;    oper[cnt].pos=i;    oper[cnt].value=a[i];
    135         }
    136         
    137         for(int i=1;i<=m;i++)
    138         {
    139             scanf("%s",ch);
    140             if(ch[0]=='Q')
    141             {
    142                 x=get();    y=get();    k=get();
    143                 oper[++cnt].opt=3;    oper[cnt].l=x;    oper[cnt].r=y;    oper[cnt].k=k;
    144                 oper[cnt].cnt=++Num;
    145             }
    146             else
    147             {
    148                 x=get();    y=get();
    149                 oper[++cnt].opt=2;    oper[cnt].pos=x;    oper[cnt].value=a[x];
    150                 oper[++cnt].opt=1;    oper[cnt].pos=x;    oper[cnt].value=y;
    151                 a[x]=y;
    152             }
    153         }
    154         
    155         Solve(1,cnt,0,INF);
    156         
    157         for(int i=1;i<=Num;i++)
    158         printf("%d
    ",Ans[i]);
    159 }
    View Code
  • 相关阅读:
    Spring boot unable to determine jdbc url from datasouce
    Unable to create initial connections of pool. spring boot mysql
    spring boot MySQL Public Key Retrieval is not allowed
    spring boot no identifier specified for entity
    Establishing SSL connection without server's identity verification is not recommended
    eclipse unable to start within 45 seconds
    Oracle 数据库,远程访问 ora-12541:TNS:无监听程序
    macOS 下安装tomcat
    在macOS 上添加 JAVA_HOME 环境变量
    Maven2: Missing artifact but jars are in place
  • 原文地址:https://www.cnblogs.com/BearChild/p/6434564.html
Copyright © 2011-2022 走看看