zoukankan      html  css  js  c++  java
  • CF1039E Summer Oenothera Exhibition 根号分治+LCT+ST表

    好神仙的数据结构题呀! 

    code: 

    #include <cstdio> 
    #include <cstring> 
    #include <vector>   
    #include <cmath>   
    #include <algorithm>   
    #define BL 250     
    #define N 100006    
    #define inf 0x7fffffff
    #define setIO(s) freopen(s".in","r",stdin)  
    using namespace std;  
    int n,arr[N];  
    namespace ST 
    {    
    	int maxv[18][N],minv[18][N],bin[18];    
    	inline void init() 
    	{
    		int i,j;     
    		for(i=0;i<18;++i)  bin[i]=(1<<i);          
    		for(i=1;i<=n+1;++i)   
    			maxv[0][i]=minv[0][i]=arr[i];          
    		for(i=1;i<18;++i) 
    			for(j=1;j+bin[i]-1<=n+1;++j) 
    			{
    				maxv[i][j]=max(maxv[i-1][j],maxv[i-1][j+bin[i-1]]);   
    				minv[i][j]=min(minv[i-1][j],minv[i-1][j+bin[i-1]]);       
    			}    
    	}
    	inline int q_max(int l,int r) 
    	{        
    		int p=log2(r-l+1);    
    		return max(maxv[p][l],maxv[p][r-bin[p]+1]);   
    	}   
    	inline int q_min(int l,int r) 
    	{  
    		int p=log2(r-l+1);   
    		return min(minv[p][l],minv[p][r-bin[p]+1]);  
    	}    
    	inline int query(int l,int r) { return q_max(l,r)-q_min(l,r); }
    };    
    namespace LCT
    {      
        #define lson s[x].ch[0]
        #define rson s[x].ch[1] 
        int sta[N];  
        struct data 
        {  
            int ch[2],rev,f,siz;                
        }s[N];            
        inline int get(int x) { return s[s[x].f].ch[1]==x; } 
        inline int isr(int x) {  return s[s[x].f].ch[0]!=x&&s[s[x].f].ch[1]!=x; }
        inline void pushup(int x) 
        {
        	s[x].siz=s[lson].siz+s[rson].siz+1;     
        }     
        inline void rotate(int x)
        {
            int old=s[x].f,fold=s[old].f,which=get(x); 
            if(!isr(old)) 
            	s[fold].ch[s[fold].ch[1]==old]=x;  
            s[old].ch[which]=s[x].ch[which^1]; 
            if(s[old].ch[which]) 
                s[s[old].ch[which]].f=old; 
            s[x].ch[which^1]=old,s[old].f=x,s[x].f=fold; 
            pushup(old),pushup(x);     
        }    
        inline void mark(int x)
        {
            swap(lson,rson);   
            s[x].rev^=1;   
        }
        inline void pushdown(int x)
        {
            if(s[x].rev)
            {
                if(lson) 
                	mark(lson);
                if(rson) 
                	mark(rson);
                s[x].rev=0;  
            }
        }
        inline void splay(int x)
        {
            int u=x,v=0,fa; 
            for(sta[++v]=u;!isr(u);u=s[u].f) 
            	sta[++v]=s[u].f;       
            for(;v;--v) 
            	pushdown(sta[v]);  
            for(u=s[u].f;(fa=s[x].f)!=u;rotate(x)) 
                if(s[fa].f!=u)
                    rotate(get(fa)==get(x)?fa:x);  
        }
        inline void Access(int x)
        {
            for(int y=0;x;y=x,x=s[x].f)
                splay(x),rson=y,pushup(x);    
        }        
        inline void link(int x,int y) { s[y].f=x; }      
        // 断掉 y 与父亲     
        inline void cut(int y)
        {    
        	Access(y),splay(y);     
            s[s[y].ch[0]].f=0,s[y].ch[0]=0,pushup(y);  
        }
        inline int frt(int x)  
        {
        	while(lson) 
        		x=lson;    
        	return x;   
        }
        #undef lson
        #undef rson
    };   
    struct ask 
    {   
    	int k,id; 
    	bool operator<(const ask b) const { return k<b.k; }
    }q[N];     
    int h[N],mark[N],A[N],Ans[N];    
    vector<int>G[N];     
    int find(int x,int k) 
    {
    	int l=x+1,r=n+1,mid;     
    	for(mid=(l+r)>>1;l<r;mid=(l+r)>>1)     
    	{
    		int cu=ST::query(x,mid);     
    		if(cu>k)   
    			r=mid; 
    		else 
    			l=mid+1;    
    	} 
    	return mid;  
    }                          
    int main() 
    {
    	// setIO("input"); 
    	int i,j,B,W,Q;      
    	scanf("%d%d%d",&n,&W,&Q);  
    	B=sqrt(n);       
    	for(i=1;i<=n;++i)   
    		scanf("%d",&arr[i]);  
    	arr[n+1]=inf;           
    	ST::init();      
    	for(i=1;i<=n;++i)  
    		LCT::s[i].siz=1;  
    	for(i=1;i<=Q;++i)     
    	{
    		scanf("%d",&q[i].k); 
    		A[i]=q[i].k=W-q[i].k,q[i].id=i;  
    	}       
    	sort(q+1,q+1+Q);       
    	for(i=1;i<=n;++i)   
    		h[i]=i,LCT::s[i].f=i+1,G[1].push_back(i);           
    	for(i=1;i<=Q;++i) 
    	{
    		int o,t,k;      
    		for(o=j=0;j<G[i].size();++j)    
    		{
    			int u=G[i][j];    
    			LCT::cut(u);         
    			for(k=h[u]+1;ST::query(u,k)<=q[i].k&&k-u<=B&&k<=n;++k);      
    			if(k-u>B)  
    				mark[u]=1;   
    			else 
    			{
    				h[u]=k; 
    				LCT::s[u].f=h[u]; 
    				G[lower_bound(q+1,q+1+Q,(ask){ST::query(u,h[u]),0})-q].push_back(u);  
    			} 
    		}
    		for(j=1;;j=find(j,q[i].k),++o) 
    		{
    			if(!mark[j])   
    			{
    				LCT::Access(j);   
    				LCT::splay(j);    
    				o+=LCT::s[j].siz-1;    
    				j=LCT::frt(j);   
    			}
    			if(j>n)
    				break;    
    		}
    		Ans[q[i].id]=o-1;  
    	}
    	for(i=1;i<=Q;++i)   
    		printf("%d
    ",Ans[i]);  
    	return 0;  
    }
    

      

      

  • 相关阅读:
    Linux初学
    Linux初学
    EntityFramework IEnumerable,IQueryable ,Include
    EntityFramework 4/5/6 中执行自定义SQL语句
    ServiceStack Web Service 创建与调用简单示列
    ServiceStack 概念
    Couchbase 环境搭建与使用(C#)
    Redis 环境搭建与使用(C#)
    分享几段JavaScript
    Activemq 平台搭建与C#示列
  • 原文地址:https://www.cnblogs.com/guangheli/p/12426958.html
Copyright © 2011-2022 走看看