权值分块,虽然渐进复杂度不忍直视,但其极小的常数使得实际运行起来比平衡树快,大多数情况和递归版权值线段树差不多,有时甚至更快。但是被zkw线段树完虐。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 using namespace std; 5 #define N 1000001 6 int maxv,minv=2147483647; 7 int n,op,a,m,ma[N],en,l[1100],r[1100],sumv[1100],sz,sum,num[N],Num,CH[12]; 8 bool b[N]; 9 inline void R(int &x){ 10 char c=0;int f=1; 11 for(;c<‘0‘||c>‘9‘;c=getchar())if(c==‘-‘)f=-1; 12 for(x=0;c>=‘0‘&&c<=‘9‘;c=getchar())(x*=10)+=(c-‘0‘); 13 x*=f; 14 } 15 inline void P(int x) 16 { 17 if(!x){putchar(‘0‘);puts("");return;} 18 if(x<0){putchar(‘-‘);x=-x;}Num=0; 19 while(x>0)CH[++Num]=x%10,x/=10; 20 while(Num)putchar(CH[Num--]+48);puts(""); 21 } 22 void makeblock() 23 { 24 sz=sqrt(n); if(!sz) sz=1; r[0]=-1; 25 for(sum=1;sum*sz<n-1;sum++) 26 { 27 l[sum]=r[sum-1]+1; 28 r[sum]=sz*sum-1; 29 for(int i=l[sum];i<=r[sum];i++) num[i]=sum; 30 } 31 l[sum]=r[sum-1]+1; 32 r[sum]=n-1; 33 for(int i=l[sum];i<=r[sum];i++) num[i]=sum; 34 } 35 inline void Insert(const int &x){if(b[x]) return; b[x]=1; sumv[num[x]]++;} 36 inline void Delete(const int &x){if(!b[x]) return; b[x]=0; sumv[num[x]]--;} 37 inline int Next(const int &x) 38 { 39 for(int i=x+1;i<=r[num[x]];i++) if(b[i]) return i; 40 for(int i=num[x]+1;i<=sum;i++) if(sumv[i]) 41 for(int j=l[i];j<=r[i];j++) 42 if(b[j]) return j; 43 return -1; 44 } 45 inline int Pre(const int &x) 46 { 47 for(int i=x-1;i>=l[num[x]];i--) if(b[i]) return i; 48 for(int i=num[x]-1;i>=1;i--) if(sumv[i]) 49 for(int j=r[i];j>=l[i];j--) 50 if(b[j]) return j; 51 return -1; 52 } 53 inline int Min() 54 { 55 for(int i=1;i<=sum;i++) if(sumv[i]) 56 for(int j=l[i];j<=r[i];j++) if(b[j]) return j; 57 return -1; 58 } 59 inline int Max() 60 { 61 for(int i=sum;i>=1;i--) if(sumv[i]) 62 for(int j=r[i];j>=l[i];j--) if(b[j]) return j; 63 return -1; 64 } 65 int main() 66 { 67 scanf("%d%d",&n,&m); 68 makeblock(); 69 for(int i=1;i<=m;i++) 70 { 71 scanf("%d",&op); if(op!=3&&op!=4) scanf("%d",&a); 72 if(op==1) Insert(a); 73 else if(op==2) Delete(a); 74 else if(op==3) printf("%d\n",Min()); 75 else if(op==4) printf("%d\n",Max()); 76 else if(op==5) printf("%d\n",Pre(a)); 77 else if(op==6) printf("%d\n",Next(a)); 78 else printf("%d\n",b[a] ? 1 : -1); 79 } 80 return 0; 81 }
时间: 2024-10-21 09:45:47