• POJ2104 K-th Number(整体二分)


    题解

    又一次做这个题上一次用的是线段树上二分。这次用的是整体二分。结果:

    (第一个是整体二分)

    整体二分就是对于所有查询都二分一个值。然后根据能不能成立把询问修改分成两部分,然后第二部分继承第一部分的信息,然后这两部分继续递归。直到答案的值域为一个数,将这些询问的答案设成这个数就行了。

    实现的时候,递归传4个参分别是询问的编号范围,和值域。

    模板题还是要看代码理解。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=100000;
     8 const int M=5010;
     9 const int INF=0x3f3f3f3f;
    10 int n,m,ans[M],tr[N],cnt;
    11 struct query{
    12     int x,y,k,id,type;
    13 }q[N+M],c2[N+M],c1[N+M];
    14 int lowbit(int x){
    15     return x&-x;
    16 }
    17 void add(int x,int w){
    18     for(int i=x;i<=n;i+=lowbit(i)){
    19         if(i==0)break;
    20         tr[i]+=w;
    21     }
    22 }
    23 int getsum(int x){
    24     int ans=0;
    25     for(int i=x;i>=1;i-=lowbit(i)){
    26         if(i==0)break;
    27         ans+=tr[i];
    28     }
    29     return ans;
    30 }
    31 void solve(int l,int r,int L,int R){
    32     if(l>r)return;
    33     if(L==R){
    34         for(int i=l;i<=r;i++){
    35             if(q[i].type==2)ans[q[i].id]=L;
    36         }
    37         return;
    38     }
    39     int mid=(L+R)>>1;
    40     int lnow=0;int rnow=0;
    41     for(int i=l;i<=r;i++){
    42         if(q[i].type==1){
    43             if(q[i].x<=mid){
    44                 add(q[i].id,q[i].y);
    45                 c1[++lnow]=q[i];    
    46             }
    47             else c2[++rnow]=q[i];
    48         }
    49         else{
    50             int tmp=getsum(q[i].y)-getsum(q[i].x-1);
    51             if(q[i].k<=tmp)c1[++lnow]=q[i];
    52             else {
    53                 q[i].k-=tmp;
    54                 c2[++rnow]=q[i];    
    55             }
    56         }
    57     }
    58     for(int i=1;i<=lnow;i++){
    59         if(c1[i].type==1)add(c1[i].id,-c1[i].y);
    60     }
    61     for(int i=1;i<=lnow;i++){
    62         q[l+i-1]=c1[i];
    63     }
    64     for(int i=1;i<=rnow;i++){
    65         q[l+lnow+i-1]=c2[i];
    66     }
    67     solve(l,l+lnow-1,L,mid);
    68     solve(l+lnow,r,mid+1,R);
    69 }
    70 int main(){
    71     scanf("%d%d",&n,&m);
    72     for(int i=1;i<=n;i++){
    73         int x;
    74         scanf("%d",&x);
    75         q[i].id=i;q[i].x=x;q[i].type=1;q[i].y=1;
    76     }
    77     cnt=n;
    78     for(int i=1;i<=m;i++){
    79         int x,y,k;
    80         scanf("%d%d%d",&x,&y,&k);
    81         q[++cnt].id=i;q[cnt].x=x;q[cnt].y=y;q[cnt].k=k;q[cnt].type=2;
    82     }
    83     solve(1,cnt,-INF,INF);
    84     for(int i=1;i<=m;i++){
    85         printf("%d
    ",ans[i]);
    86     }
    87     return 0;
    88 } 
  • 相关阅读:
    oracle和mysql功能相同的函数
    五个人二个月为什么不等于十个人一个月
    Oracle—RMAN完全恢复
    UVA 208 Firetruck
    sql server2005 express和Northwind数据库安装
    机器学习理论与实战(十一)关联规则分析Apriori
    JavaScript前世今生
    Maclean Liu对Oracle Database 12c新特性研究汇总
    amcharts报表制作
    HDU 4274 Spy's Work (树 DFS)
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9461948.html
Copyright © 2020-2023  润新知