zoukankan      html  css  js  c++  java
  • 【题解】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;
    }
    
  • 相关阅读:
    ArrayList 和 LinkList 的区别
    fork()相关的源码解析
    http协议状态码及其意义
    数据库的死锁相关知识
    JDBC事务的相关知识
    请求http页面的相关过程
    static 关键字的作用
    计算机网络网络层的IP地址划分及子码
    文件的相关操作.
    set集合和深浅拷贝
  • 原文地址:https://www.cnblogs.com/h-lka/p/12869200.html
Copyright © 2011-2022 走看看