• 解题报告:luogu P2787


    尝试 Ynoi 无果,滚来切屑题了。

    题目链接:P2787 语文1(chin1)- 理理思维

    区间排序一看就很谔谔,记得有一道 Ynoi 也是这样的。

    Ynoi? 那不行,看到有枚举暴力的标签,感觉到可以搞事情。

    值域很小(只有 (26)),所以可以枚举值域得到个数,修改即可。

    比如说我们先查询 (A/a) 出现的次数,然后把这个区间前这些全修改成 (A/a),然后对每个数都这样操作,这样只有 (mathcal O(26log n)) 的复杂度。

    这样就只有 (2) 个操作了。

    剩下的一些和序列操作类似,好写多了。

    注意懒标记即可。

    (Code:)

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    using namespace std;
    
    #define read(x) scanf("%d",&x)
    #define MAXN 50005
    
    struct node
    {
    	int sum[30],l,r,lazy;
    	node(){lazy=0;memset(sum,0,sizeof(sum));l=r=0;}
    }a[MAXN<<2];
    int n,m;
    char s[MAXN],c;
    int t,l,r;
    
    inline int get(char a){return (a<='z'&&a>='a')?a-'a'+1:a-'A'+1;}
    
    inline void update(int k){for(register int i=1;i<=26;i++) a[k].sum[i]=a[k<<1].sum[i]+a[k<<1|1].sum[i];}
    
    inline void build(int k,int l,int r)
    {
    	a[k].l=l,a[k].r=r;
    	if(l==r)
    	{
    		int v=get(s[l]);
    		a[k].sum[v]=1;
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(k<<1,l,mid),build(k<<1|1,mid+1,r);
    	update(k);
    }
    
    inline void lazydown(int k)
    {
    	if(a[k].l==a[k].r){a[k].lazy=0;return;}
    	for(register int i=1;i<=26;i++) a[k<<1].sum[i]=a[k<<1|1].sum[i]=0;
    	a[k<<1].sum[a[k].lazy]=a[k<<1].r-a[k<<1].l+1;
    	a[k<<1|1].sum[a[k].lazy]=a[k<<1|1].r-a[k<<1|1].l+1;
    	a[k<<1].lazy=a[k].lazy;
    	a[k<<1|1].lazy=a[k].lazy;
    	a[k].lazy=0;
    	return;  
    }
    
    inline void turn(int k,int l,int r,int x)
    {
    	if(a[k].l==l&&a[k].r==r)
    	{
    		for(register int i=1;i<=26;i++) a[k].sum[i]=0;
    		a[k].sum[x]=a[k].r-a[k].l+1;
    		a[k].lazy=x;
    		return;
    	}
    	if(a[k].lazy) lazydown(k);
    	int mid=(a[k].l+a[k].r)>>1;
    	if(r<=mid) turn(k<<1,l,r,x);
    	else if(l>mid) turn(k<<1|1,l,r,x);
    	else turn(k<<1,l,mid,x),turn(k<<1|1,mid+1,r,x);
    	update(k);
    }
    
    inline int query(int k,int l,int r,int x)
    {
    	if(a[k].lazy) lazydown(k);
    	if(a[k].l==l&&a[k].r==r) return a[k].sum[x];
    	int mid=(a[k].l+a[k].r)>>1;
    	if(r<=mid) return query(k<<1,l,r,x);
    	else if(l>mid) return query(k<<1|1,l,r,x);
    	else return query(k<<1,l,mid,x)+query(k<<1|1,mid+1,r,x);
    }
    
    int main()
    {
    	read(n),read(m);
    	scanf("%s",s);
    	for(register int i=n;i>=1;i--) s[i]=s[i-1];
    	build(1,1,n);
    	for(register int j=1;j<=m;j++)
    	{
    		read(t),read(l),read(r);
    		if(t==1) cin>>c,printf("%d
    ",query(1,l,r,get(c)));
    		else if(t==2) cin>>c,turn(1,l,r,get(c));
    		else
    		{
    			int ll=l,now[30]={0};
    			for(register int i=1;i<=26;i++) now[i]=query(1,l,r,i);
    			for(register int i=1;i<=26;i++)
    			{
    				if(ll>r) break;
    				if(now[i])
    				{
    					turn(1,ll,ll+now[i]-1,i);
    					ll+=now[i];
    				}
    			}
    		}
    	}
    	return 0;
    }
    

    不开 (O2) 死得有点惨,不知道为什么。

  • 相关阅读:
    iframe脸面的页面和父页面之间的交互方法
    iframe高度自适应
    获取html元素所在页面的坐标
    自制的几个jquery插件
    将DataTable转换成Json格式
    QL 获取当前日期,年、月、日、周、时、分、秒
    DropdownList异步刷新GridView数据
    图片热区——map的用法
    Chart控件文档
    母版页改变被嵌套的页面中的控件ID的解决方法
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/12888817.html
Copyright © 2020-2023  润新知