• 『P1177』与『P2572』联合题解


    P1177

    基数排序

    基本理论就是把一个数字分成k个关键字,每次对n个数同时对于k关键字排序

    时间复杂度(O(n imes frac{n_max}{radix})),空间复杂度是(O(n+radix))

    radix为取的基数,通常取 (65536) 或者是 (256)

    (NOI)(NOIp) 的配置大概取 (256) 为基数能卡进 (L1) 高速缓存,但是你取 (65536) 在联赛里就卡不进 (L1) 内存访问不连续就会非常慢……(但是luogu评测姬 (L1) 似乎大得离谱

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define INF 1<<30
    #define int long long 
    #define pb push_back
    %:define ill unsigned long long 
    %:define lowbit(x) (x&(-x))
    %:define Int unsigned int 
    #define pii pair<int,int>
    
    template<typename _T>
    inline void read(_T &x)
    {
    	x = 0;int f= 1;char s = getchar();
    	while(s<'0'||s>'9'){f=1;if(s=='-')f=-1;s=getchar();}
    	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
    	x*=f;
    }
    
    const int U = 256;
    const int BIT = 8;
    
    const int np = 1e5 + 5;
    
    int n;
    int a[np];
    int b[np];
    int bac[np];
    
    inline int Get(int x,int d)
    {
    	return (x >> BIT * d) & (U - 1);
    }
    
    inline void sort_()
    {
    	for(int d=0;d<4;d++)
    	{
    		for(int i=0;i<U;i++) bac[i] = 0;
    		for(int i=1;i<=n;i++) bac[Get(a[i],d)]++;
    		for(int i=0;i<U;i++) bac[i] += bac[i-1];
    		for(int i=n;i>=1;i--) b[bac[Get(a[i],d)]--] = a[i];
    		for(int i=1;i<=n;i++) a[i] = b[i];
    	}
    }
    
    signed main()
    {
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i]);
    	
    	sort_();
    	
    	for(int i=1;i<=n;i++)
    	cout<<a[i]<<" ";
    }
    

    P2572

    裸的数据结构题,题目已经明示线段树维护。

    (一开始我还想敲一个珂朵莉苟过去,但直接被卡成(30pts)

    难点在于懒标记的维护与下放,对于懒标记问题

    思考问题的时候需要牢牢把握一下几点:

    懒标记本质是对自己儿子修改的信号
    需要思考懒标记之间的优先级关系
    需要思考下放懒标记时对子节点懒标记的影响

    这样来思考问题解决懒标记还是蛮轻松的

    (把这篇整上来只是想记录一下这种方法,而不是就题论题

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define INF 1<<30
    #define int long long 
    #define pb push_back
    %:define ill unsigned long long 
    %:define lowbit(x) (x&(-x))
    %:define Int unsigned int 
    
    template<typename _T>
    inline void read(_T &x)
    {
    	x = 0;int f= 1;char s = getchar();
    	while(s<'0'||s>'9'){f=1;if(s=='-')f=-1;s=getchar();}
    	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
    	x*=f;
    }
    
    const int np = 1e5 + 5;
    
    struct node{
    	int l,r;
    	int sum;
    	int lmax[2],rmax[2],maxn_len[2];
    	int cov[2];
    	int typ_f;
    	node *ls,*rs;
    	
    	inline bool inrange(int L,int R){return L<=l&&r<=R;}
    	inline bool outofrange(int L,int R){return r < L||R < l;}
    	
    	inline void pushup()
    	{
    		sum = ls->sum + rs->sum;
    		for(int i=0;i<=1;i++)
    		{
    			maxn_len[i] = ls->rmax[i] + rs->lmax[i];
    			maxn_len[i] = max(maxn_len[i] , ls->maxn_len[i]);
    			maxn_len[i] = max(maxn_len[i] , rs->maxn_len[i]);
    			if(ls->lmax[i] == ls->r - ls->l + 1 )lmax[i] = ls->lmax[i] + rs->lmax[i];
    			else lmax[i] = ls->lmax[i];
    			if(rs->rmax[i] == rs->r - rs->l + 1)rmax[i] = rs->rmax[i] + ls->rmax[i];
    			else rmax[i] = rs->rmax[i];			
    		}
    	}
    	
    	inline void pushdown()
    	{
    		if(cov[1])
    		{
    			ls->maketag(1);
    			rs->maketag(1);
    			cov[1] = 0;
    		 } 
    		if(cov[0])
    		{
    			ls->maketag(0);
    			rs->maketag(0);
    			cov[0] = 0;
    		 } 
    		if(typ_f) ls->make_f() , rs->make_f(),typ_f^=1;
    	}
    	
    	inline void make_f()
    	{
    		sum = (r - l + 1) - sum;
    		swap(lmax[1],lmax[0]);
    		swap(rmax[1],rmax[0]);
    		swap(maxn_len[1],maxn_len[0]);
    		typ_f ^= 1;
    	}
    		
    	inline void maketag(int vl)
    	{
    		sum = (r - l + 1) * vl;
    		lmax[vl] = r - l + 1 , lmax[!vl] = 0;
    		rmax[vl] = r - l + 1 , rmax[!vl] = 0;
    		maxn_len[vl] = r-l + 1,maxn_len[!vl] = 0;
    		cov[vl] = 1;cov[!vl] = typ_f = 0;
    	}
    	
    	inline int query_opt_3(int L,int R)
    	{
    		if(inrange(L,R))
    		{
    			return sum;
    		}
    		else
    		{	
    			if(!outofrange(L,R))
    			{
    				pushdown();
    				return ls->query_opt_3(L,R) + rs->query_opt_3(L,R);
    			 } 
    			else return 0;
    		}
    	}
    	
    	inline int query_opt_4(int L,int R)
    	{
    		if(inrange(L,R))
    		{
    			return maxn_len[1];
    		}
    		else
    		{
    			if(!outofrange(L,R))
    			{
    				pushdown();
    				int mid = l + r >> 1; 
    				int x = 0;
    				
    				if( L<= mid && mid<=R && L<=mid + 1 && mid + 1<=R && ls->rmax[1] && rs->lmax[1])
    				{
    					if(mid + rs->lmax[1] <= R) x+= rs->lmax[1];
    					else x += R-(mid + 1) + 1;
    					if(L <= mid - ls->rmax[1] + 1) x += ls->rmax[1];
    					else x += mid - L + 1; 
    				}
    				return max({x ,ls->query_opt_4(L,R) , rs->query_opt_4(L,R) });
    			} 
    			else return 0;
    		}
    	}
    	
    	inline void cover(int L,int R,int vl)
    	{
    		if(inrange(L,R))
    		{
    			maketag(vl);
    			return ;
    		}
    		else
    		{
    			if(!outofrange(L,R))
    			{
    				pushdown();
    				ls->cover(L,R,vl);
    				rs->cover(L,R,vl);
    				pushup();
    			}
    		}
    	}
    	
    	inline void qf(int L,int R)
    	{
    		if(inrange(L,R))
    		{
    			make_f();
    			return;
    		}
    		else
    		{
    			if(!outofrange(L,R))
    			{
    				pushdown();
    				ls->qf(L,R);
    				rs->qf(L,R);
    				pushup();
    			}
    		}
    	}
    	
    }mem[np * 2 + 10] , *pool = mem;
    int a[np];
    inline node *New(){return ++pool;}
    
    inline node *build(int L,int R)
    {
    	node *u = New();
    	u->l = L;
    	u->r = R;
    	if(L == R)
    	{
    		u->ls = u->rs = NULL;
    		if(a[L]) u->sum = u->maxn_len[1] = u->lmax[1] = u->rmax[1] = 1;
    		else u->maxn_len[0] = u->lmax[0] = u->rmax[0] = 1;
    	}
    	else 
    	{
    		int mid = L+R>>1;
    		u->ls = build(L,mid);
    		u->rs = build(mid + 1,R);
    		u->pushup();
    	}
    	return u;
    }
    node *rot;
    
    
    signed main()
    {
    	int n,m;
    	read(n);
    	read(m);
    	for(int i=1;i<=n;i++)
    	read(a[i]);
    	
    	rot = build(1,n);
    	
    	for(int i=1,opt,l,r;i<=m;i++)
    	{
    		read(opt);
    		read(l);
    		read(r);
    		l++;
    		r++;
    		switch(opt)
    		{
    			case 0:{
    				rot->cover(l,r,0);
    				break;
    			}
    			case 1:{
    				rot->cover(l,r,1);
    				break;
    			}
    			case 2:{
    				rot->qf(l,r);
    				break;
    			}
    			case 3:{
    				cout<<rot->query_opt_3(l,r)<<'
    ';
    				break;
    			}
    			case 4:{
    				cout<<rot->query_opt_4(l,r)<<'
    ';
    				break;
    			}
    		}
    	}
    	return 0;
    }
    

    至于为什么是联合题解

    因为两个题的字数加起来不是很多,分开写有点浪费而已

    (End)

  • 相关阅读:
    [BZOJ5339] [TJOI2018]教科书般的亵渎
    拉格朗日插值法
    [LOJ#2340] [WC2018] 州区划分
    [洛谷4609] [FJOI2016]建筑师
    [CF960G] Bandit Blues
    [BZOJ2115] [WC2011] Xor
    [Codeforces 809E] Surprise me!
    无需AutoCAD,用C#生成DWG文件
    扩展方法的几点总结
    RedirectStandardOutput
  • 原文地址:https://www.cnblogs.com/-Iris-/p/15350261.html
Copyright © 2020-2023  润新知