• [bzoj3065] 带插入区间K小值


      腾爷手把手带你卡OJ系列。

      靠谱些的做法应该是替罪羊树套权值线段树= =

      然而某奇怪论文表示强行块状链表并不会被卡..而且还能进第一页233。

      所以就跟着腾爷学块链了= =

      感觉块链就是一本正经的暴力。。。分块后,块与块之间是用链表的姿势联系在一起的。

      插入的话强行插进那个块里,如果当前块的太大的话,就分成两块。。

      其他东西和分块一样。

      每个块里面记录原数列和排序后的,每次查找第k大的时候二分答案,对于每个二分出的答案mid,在每个块里面二分。。。

      单次查询复杂度O(n/B*log²n)....这种复杂度能够艹翻各种树套树简直是。。。

      其实如果对于每个块建一颗权值线段树的话,可以少掉一个log。。但实测线段树的常数比一个log的影响还大233

      至于块大小的正确选择。。先把总的复杂度算出来。然后利用奇怪的函数图像绘制工具就可以搞出来啦

      块的大小在750左右比较科学= =。。。 

      腾爷轻松进前10%%%。。。我改半天越跑越慢>_<最后只挤进了第二

      这个故事告诉我们千万不要怀疑分块的速度&&千万不要试图和神犇比常数

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<algorithm>
      7 using namespace std;
      8 const int kuai=423;
      9 int mp[233][888],pre[233][888],sz[233],aft[233];
     10 int tmp[2333];
     11 int i,j,k,n,m,num,mn,mx,lastans;
     12   
     13 int ra;char rx;
     14 inline int read(){
     15     rx=getchar(),ra=0;
     16     while(rx<'0'||rx>'9')rx=getchar();
     17     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     18 }
     19   
     20 inline int min(int a,int b){return a<b?a:b;}
     21 inline int max(int a,int b){return a>b?a:b;}
     22 inline void swap(int &a,int &b){int c=a;a=b,b=c;}
     23 inline int getk(int x,int y,int k){
     24     int l=mn,r=mx,mid,mnnum,i,l1,r1,mid1;
     25     short lpos,rpos;
     26     for(lpos=1;sz[lpos]<x;lpos=aft[lpos])x-=sz[lpos];
     27     for(rpos=1;sz[rpos]<y;rpos=aft[rpos])y-=sz[rpos];
     28     if(lpos!=rpos){
     29         for(i=1,tmp[0]=0;i<=y;i++)tmp[++tmp[0]]=pre[rpos][i];
     30         for(i=x;i<=sz[lpos];i++)tmp[++tmp[0]]=pre[lpos][i];
     31         sort(tmp+1,tmp+1+tmp[0]);
     32     }
     33     while(l<r){
     34         mid=l+r+1>>1,mnnum=0;
     35         if(lpos==rpos){
     36             for(i=x;i<=y;i++)if(pre[lpos][i]<mid)mnnum++;
     37         }else{
     38             for(l1=0,r1=tmp[0];l1<r1;)
     39                     if(tmp[(mid1=l1+r1+1>>1)]<mid)l1=mid1;else r1=mid1-1;
     40             mnnum=l1;
     41             for(i=aft[lpos];i!=rpos&&mnnum<k;mnnum+=l1,i=aft[i])
     42                 for(l1=0,r1=sz[i];l1<r1;)
     43                     if(mp[i][(mid1=l1+r1+1>>1)]<mid)l1=mid1;else r1=mid1-1;
     44         }
     45         if(mnnum<k)l=mid;else r=mid-1;
     46     }
     47     return l;
     48 }
     49 inline void change(int x,int v){
     50     register int i,j;
     51     mn=min(mn,v),mx=max(mx,v);
     52     for(i=1;sz[i]<x;i=aft[i])x-=sz[i];
     53     if(pre[i][x]==v)return;
     54     for(j=1;j<=sz[i]&&mp[i][j]<pre[i][x];j++);
     55     mp[i][j]=pre[i][x]=v;
     56     while(j>1&&mp[i][j-1]>mp[i][j])swap(mp[i][j],mp[i][j-1]),j--;
     57     while(j<sz[i]&&mp[i][j+1]<mp[i][j])swap(mp[i][j],mp[i][j+1]),j++;
     58 }
     59   
     60 inline void split(int x){
     61     aft[++num]=aft[x],aft[x]=num,sz[num]=sz[x]>>1,sz[x]-=sz[num],
     62     memcpy(pre[num]+1,pre[x]+1+sz[x],sz[num]<<2),memcpy(mp[num],pre[num],(sz[num]+1)<<2),
     63     sort(mp[num]+1,mp[num]+1+sz[num]),
     64     memcpy(mp[x],pre[x],(sz[x]+1)<<2),sort(mp[x]+1,mp[x]+1+sz[x]);
     65 }
     66 inline void insert(int x,int v){
     67     int i,j;
     68     mn=min(mn,v),mx=max(mx,v);
     69     for(i=1;sz[i]+1<x;i=aft[i])x-=sz[i];
     70     //pre[i][++sz[i]]=v;
     71     sz[i]++;
     72     for(j=sz[i];j>x;j--)pre[i][j]=pre[i][j-1];
     73     pre[i][x]=v;
     74     if(sz[i]>=kuai*2)split(i);else
     75         for(mp[i][sz[i]]=v,j=sz[i];j>1&&mp[i][j-1]>mp[i][j];)swap(mp[i][j],mp[i][j-1]),j--;
     76       
     77 }
     78 int main(){
     79     n=read();mn=70023,mx=0;
     80     num=(n+kuai-1)/kuai;int now=1;
     81     for(i=1;i<=n;i++)
     82         now+=sz[now]==kuai,sz[now]++,
     83         mp[now][sz[now]]=pre[now][sz[now]]=read();
     84     for(i=1;i<=num;i++)sort(mp[i]+1,mp[i]+1+sz[i]);
     85     for(i=1;i<num;i++)aft[i]=i+1;
     86     for(i=2,mn=mp[1][1],mx=mp[1][sz[1]];i<=num;i++)
     87         mn=min(mn,mp[i][1]),mx=max(mx,mp[i][sz[i]]);
     88       
     89 //  printf("  %d %d
    ",mn,mx);
     90       
     91     int x,y,z;char id;
     92     for(int m=read();m;m--){
     93         for(id=getchar();id<'A'||id>'Z';id=getchar());
     94         x=read()^lastans,y=read()^lastans;
     95         if(id=='Q')z=read()^lastans,lastans=getk(x,y,z),
     96 //                  printf("       %d--%d %d
    ",x,y,z),
     97                     printf("%d
    ",lastans);else
     98         if(id=='I')insert(x,y);else
     99         change(x,y);
    100 //      for(i=1;i;printf("  "),i=aft[i])for(j=1;j<=sz[i];j++)printf(" %d",pre[i][j]);puts("");
    101 //      for(i=1;i;printf("  "),i=aft[i])for(j=1;j<=sz[i];j++)printf(" %d",mp[i][j]);puts("");
    102     }
    103     return 0;
    104 }
    View Code

      PS:腾爷喜闻乐见地把原来论文里的程序挤出了第一页2333

  • 相关阅读:
    Dynamic CRM 2013学习笔记(四)单据编号及插件批量注册工具
    Dynamic CRM 2013学习笔记(三)快速创建实体 EntityCreater
    Dynamic CRM 2013学习笔记(二)插件基本用法及调试
    Dynamic CRM 2013学习笔记(一)插件输入实体参数解析
    MVC 4 图片的上传及显示
    CRM 2013 批量更新two options的缺省值
    ASP.NET MVC & Web API Brief Introduction
    Mac下访问windows的共享文件夹
    解决Android编译so库出错问题
    解决Xcode 6 编译Cocos2d-x iOS项目失败
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5363366.html
Copyright © 2020-2023  润新知