• 整体二分


    带修改区间第k小,使用整体二分。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define lowbit(x) (x&-(x))
      6 using namespace std;
      7 #define MAXN 100005
      8 struct node
      9 {
     10     int tp,pos,val,ed,cur,addr;
     11 }que[MAXN],q1[MAXN],q2[MAXN];
     12 struct optnode
     13 {
     14     int opt,pos1,pos2,val;
     15 }opts[MAXN];
     16 int head,tail,cnt;
     17 int ans[MAXN];
     18 int n,nn,num[MAXN],q,jump[MAXN],realval[MAXN];
     19 int maxz;
     20 char opt[3];
     21 int tmp[MAXN];
     22 struct lsh
     23 {
     24     int val,id;
     25     bool operator <(lsh &t)const
     26     {
     27         return val<t.val;
     28     }
     29 }num2[MAXN];
     30 int tree[MAXN];
     31 void init(int x)
     32 {
     33     maxz=0;
     34     for(int i=1;i<=x;i++)
     35         num2[i].val=num[i],num2[i].id=i;
     36     sort(num2+1,num2+x+1);
     37     for(int i=1;i<=x;i++)
     38     {
     39         if(num2[i].val!=num2[i-1].val)
     40            ++maxz,realval[maxz]=num2[i].val;
     41         num[num2[i].id]=maxz;
     42 
     43     }
     44 }
     45 void add(int pos,int val)
     46 {
     47     while(pos<=n)
     48     {tree[pos]+=val;
     49     pos+=lowbit(pos);
     50     }
     51 }
     52 int getsum(int pos)
     53 {
     54     int tmp=0;
     55     while(pos)
     56     {
     57         tmp+=tree[pos];
     58         pos-=lowbit(pos);
     59     }
     60     return tmp;
     61 }
     62 void divide(int l,int r,int head,int tail)
     63 {
     64     if(head>tail)return;
     65     if(l==r)
     66     {
     67         for(int i=head;i<=tail;i++)
     68         {
     69             if(que[i].tp==3)
     70                 ans[que[i].addr]=l;
     71         }
     72         return;
     73     }
     74     int mid=(l+r)/2;
     75     for(int i=head;i<=tail;i++)
     76     {
     77         if(que[i].tp==1)if(num[que[i].val]<=mid)add(que[i].pos,1);
     78         if(que[i].tp==2)if(num[que[i].val]<=mid)add(que[i].pos,-1);
     79         if(que[i].tp==3)
     80             tmp[i]=getsum(que[i].ed)-getsum(que[i].pos-1);
     81     }
     82     for(int i=head;i<=tail;i++)
     83         {if(que[i].tp==1)if(num[que[i].val]<=mid)add(que[i].pos,-1);
     84          if(que[i].tp==2)if(num[que[i].val]<=mid)add(que[i].pos,1);
     85         }
     86 
     87         int l1=0,r1=0;
     88     for(int i=head;i<=tail;i++)
     89     {
     90         if(que[i].tp==3)
     91         {
     92             if(que[i].cur+tmp[i]>=que[i].val)
     93             q1[l1++]=que[i];
     94             else
     95             {
     96                 que[i].cur+=tmp[i];
     97                 q2[r1++]=que[i];
     98             }
     99         }
    100         else
    101         {
    102             if(num[que[i].val]<=mid)
    103                 q1[l1++]=que[i];
    104             else q2[r1++]=que[i];
    105         }
    106     }
    107     for(int i=0;i<l1;i++)que[head+i]=q1[i];
    108     for(int i=0;i<r1;i++)que[head+l1+i]=q2[i];
    109     divide(l,mid,head,head+l1-1);
    110     divide(mid+1,r,head+l1,tail);
    111 }
    112 
    113 int main()
    114 {
    115     int t1,t2,t3;
    116     scanf("%d%d",&n,&q);
    117     for(int i=1;i<=n;i++)scanf("%d",&num[i]),jump[i]=i;
    118     int nn=n;
    119     for(int i=1;i<=n;i++)
    120     que[++tail].pos=i,que[tail].tp=1,que[tail].val=i;
    121     for(int i=1;i<=q;i++)
    122     {
    123         scanf("%s",opt);
    124         if(opt[0]=='Q')
    125         {
    126             scanf("%d %d %d",&t1,&t2,&t3);
    127             que[++tail].tp=3,que[tail].pos=t1,que[tail].ed=t2,que[tail].val=t3;
    128             que[tail].addr=cnt++;
    129         }
    130         else{
    131             scanf("%d%d",&t1,&t2);
    132             num[++nn]=t2;
    133             que[++tail].tp=2,que[tail].pos=t1,que[tail].val=jump[t1];
    134             que[++tail].tp=1,que[tail].pos=t1,que[tail].val=nn;
    135             jump[t1]=nn;
    136         }
    137     }
    138     init(nn);
    139     divide(1,maxz,1,tail);
    140     for(int i=0;i<cnt;i++)
    141         printf("%d
    ",realval[ans[i]]);
    142     return 0;
    143 }
  • 相关阅读:
    MySQL的安装、配置与升级(版本5.x至8.x)
    Terra CW20 合约一致性对比和审计要点(一)
    ERC20代币审计流程
    非常道中小软件公司项目管理(3.3 项目外部关键成功因素)
    window bat 捕获执行失败
    批量把16进制转成10进制(c++)特别长的16进制字符串
    爱奇艺2020校招Java方向笔试题
    2020奇安信秋招Java方向试卷3
    Unity 之残影实现
    notepad++免安装版以及c/c++环境配置
  • 原文地址:https://www.cnblogs.com/hefenghhhh/p/9750901.html
Copyright © 2020-2023  润新知