• 【题解】CF1290B Irreducible Anagrams


    Link

    题目大意:对于一个字符串,每次询问一个区间,看看这个区间是不是可以划分为若干区间,这些区间内数字经过排列后可以还原原来区间。

    ( ext{Solution:})

    菜鸡笔者字符串构造该好好练练了……

    考虑基本情况:

    • 当区间长度为(1)的时候一定可行。这个不用证明吧。
    • 当区间左右端点不同时,一定可行。构造方法:令最右边与最左边相互交换即可。
    • 当区间不满足前两个性质并且颜色数大于(2)的时候一定可行。

    证明性质三:

    因为不满足性质(1,2)我们可以设它的左右端点颜色都是(x).那么,因为有至少三种颜色,我令一部分放到最开头,一部分放在最末尾,使得(x)对应的左右开头必须相连覆盖整个区间即可。

    如果只有两种颜色的话,区间端点颜色为(x.)那么我们如果令另一种颜色覆盖两头,则一定可以在这两个端点重新排列后的位置中间找到一个点分开使得区间不符合条件。

    以上就是所有情况了。至于颜色数,闲的没事可以线段树维护状压后的颜色,当然我们直接前缀和维护就行了。

    #include<bits/stdc++.h>
    using namespace std;
    int q,l,r,L;
    char s[200010];
    int sum[200010][50];
    int main(){
    	cin>>(s+1);
    	L=strlen(s+1);
    	for(int i=1;i<=L;++i)s[i]-='a';
    	for(int i=1;i<=L;++i){
    		for(int j=0;j<26;++j)sum[i][j]=sum[i-1][j];
    		sum[i][s[i]]++;
    	}
    	scanf("%d",&q);
    	while(q--){
    		vector<int>c;
    		scanf("%d%d",&l,&r);
    		if(l==r){
    			puts("Yes");
    			continue;
    		}
    		if(s[l]!=s[r]){
    			puts("Yes");
    			continue;
    		}
    		int tot=0;
    		for(int i=0;i<26;++i){
    			tot+=((sum[r][i]-sum[l-1][i])>0?1:0);
    			if(sum[r][i]-sum[l-1][i]==0)continue;
    			c.push_back(sum[r][i]-sum[l-1][i]);
    		}
    		//cout<<tot<<endl;
    		if(tot>2)puts("Yes");
    		else puts("No");
    	}
    	return 0;
    }
    
  • 相关阅读:
    字符编码与解码详解
    【Java反射机制】用反射改进简单工厂模式设计
    数据结构
    根据 中序遍历 和 后序遍历构造树(Presentation)(C++)
    【动态规划】记忆搜索(C++)
    Linux环境下安装中山大学东校区iNode客户端
    webpack前端开发环境搭建
    CSS中line-height继承问题
    MySQL中MyISAM与InnoDB的主要区别对比
    JavaScript中易混淆的DOM属性及方法对比
  • 原文地址:https://www.cnblogs.com/h-lka/p/12869200.html
Copyright © 2020-2023  润新知