zoukankan      html  css  js  c++  java
  • 【BZOJ 3196】 Tyvj 1730 二逼平衡树 分块

    分块 就是分块嘛!

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #define MAXN 1000000
    #define INF 1000000000
    #define MO 233333333
    #define LL long long
    using namespace std;
    int num[300][300];
    int init[50000+1];
    int n,m;
    int cnt,lenth;
    int Find(int tmp[300],int k)
    {
    	int L=1,R=tmp[0];
    	while(L<R)
    	{
    		int mid=(L+R)/2;
    		if(tmp[mid]>=k) R=mid;
    		else L=mid+1;
    	}
    	if(tmp[L]>=k)return L-1;
    	return L;
    }
    int Rank(int L,int R,int k)
    {
    	int ans=0;
    	int s=(L+lenth-1)/lenth,t=(R+lenth-1)/lenth;// cout<<lenth<<endl;
    	if(s!=t)
    	{
    		for(int i=L;i<=lenth*s;i++)
    			if(init[i]<k)
    				ans++;
    		s++;
    		for(int i=R;i>=lenth*(t-1)+1;i--)
    			if(init[i]<k)
    				ans++;
    		for(int i=s;i<t;i++)
    			ans+=Find(num[i],k);
    	}
    	else
    	{
    		for(int i=L;i<=R;i++)
    			if(init[i]<k) 
    				ans++;
    	}
    	return ans+1;
    }
    int Kth(int L,int R,int k)
    {
    	int s=0,t=100000000;
    	int ans=0;
    	while(s<t)
    	{
    		int mid=(s+t)/2;
    		if(Rank(L,R,mid)>k) t=mid;
    		else s=mid+1,ans=mid;
    	}
    	return ans;
    }
    void Change(int loc,int k)
    {
    	init[loc]=k;
    	int tmp=(loc+lenth-1)/lenth;
    	for(int i=1;i<=num[tmp][0];i++)
    		num[tmp][i]=init[(tmp-1)*lenth+i];
    	sort(num[tmp]+1,num[tmp]+num[tmp][0]+1);
    }
    int Before(int L,int R,int k)
    {
    	int s=(L+lenth-1)/lenth,t=(R+lenth-1)/lenth;
    	int mmax=-1;//cout<<s<<' '<<t<<endl;
    	if(s!=t)
    	{
    		for(int i=L;i<=s*lenth;i++)
    			if(init[i]<k)
    				mmax=max(mmax,init[i]);
    		s++;
    		for(int i=R;i>=(s-1)*lenth;i--)
    			if(init[i]<k)
    				mmax=max(mmax,init[i]);
    		for(int i=s;i<t;i++)
    		{
    			int x=Find(num[i],k);
    			if(x!=0)
    				mmax=max(num[i][x],mmax);
    		}
    	}
    	else
    	{
    		for(int i=L;i<=R;i++)
    			if(init[i]<k)
    				mmax=max(mmax,init[i]);
    	}
    	return mmax;
    }
    int Find_After(int tmp[300],int k)
    {
    	int L=1,R=tmp[0];
    	while(L<R)
    	{
    		int mid=(L+R)/2;
    		if(tmp[mid+1]<=k) L=mid+1;
    		else R=mid;
    	}
    	if(tmp[L]<=k) return L+1;
    	return L;
    }
    int After(int L,int R,int k)
    {
    	int s=(L+lenth-1)/lenth,t=(R+lenth-1)/lenth;
    	int mmin=100000000+1;
    	if(s!=t)
    	{
    		for(int i=L;i<=s*lenth;i++)
    			if(init[i]>k)
    				mmin=min(mmin,init[i]);
    		s++;
    		for(int i=R;i>=(s-1)*lenth;i--)
    			if(init[i]>k)
    				mmin=min(mmin,init[i]);
    		for(int i=s;i<t;i++)
    		{
    			int x=Find_After(num[i],k);
    			if(x!=num[i][0]+1)
    				mmin=min(num[i][x],mmin);
    		}
    	}
    	else
    	{
    		for(int i=L;i<=R;i++)
    			if(init[i]>k)
    				mmin=min(mmin,init[i]);
    	}
    	return mmin;
    }
    int main()
    {
    //	freopen("a.in","r",stdin);
    	cin>>n>>m; //cout<<n<<endl;
    	for(int i=1;i<=n;i++) scanf("%d",&init[i]);
    	lenth=sqrt(n)+2;
    	cnt=lenth;
    	for(int i=1;i<=cnt;i++)
    	{
    		for(int j=1;j<=lenth;j++)
    			num[i][j]=init[(i-1)*lenth+j];
    		sort(num[i]+1,num[i]+lenth+1);
    		num[i][0]=lenth;
    	}
    	if(n%lenth!=0)
    	{
    		cnt++;
    		num[cnt][0]=n%lenth;
    		for(int i=1;i<=num[cnt][0];i++)
    			num[cnt][i]=init[(cnt-1)*lenth+i];
    		sort(num[cnt]+1,num[cnt]+1+num[cnt][0]);
    	}
    	int L,R,pos,opt,k;
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d",&opt);
    		switch (opt)
    		{
    			case 1:
    				{
    					scanf("%d %d %d",&L,&R,&k); 
    					printf("%d
    ",Rank(L,R,k));
    					break;
    				}
    			case 2:
    				{
    					scanf("%d %d %d",&L,&R,&k);
    					printf("%d
    ",Kth(L,R,k));
    					break;
    				}
    			case 3:
    				{
    					scanf("%d %d",&pos,&k);
    					Change(pos,k);
    					break; 
    				}
    			case 4:
    				{
    					scanf("%d %d %d",&L,&R,&k);
    					printf("%d
    ",Before(L,R,k));
    					break;
    				}
    			case 5:
    				{
    					scanf("%d %d %d",&L,&R,&k);
    					printf("%d
    ",After(L,R,k)); 
    					break;
    				}
    		}
    
    
    	}
    
    
    	return 0;
    }
    
  • 相关阅读:
    指针函数与函数指针
    多版本python共存
    【转】手把手教你用Strace诊断问题
    gearman安装问题总结
    【转】nginx+memcached构建页面缓存应用
    【摘自张宴的"实战:Nginx"】http auth baseic模块(打开页面需要密码验证)
    【转】nginx的模块变量(HTTP核心模块变量)
    【摘自张宴的"实战:Nginx"】try_files指令
    nginx显示目录下面的文件
    【摘自张宴的"实战:Nginx"】nginx配置
  • 原文地址:https://www.cnblogs.com/ofsxb/p/5133145.html
Copyright © 2011-2022 走看看