题意

AraBellaC

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 277    Accepted Submission(s): 100


Problem Description
Princess Arabella loves the letter `C`, which earned her the epithet `ArraBellaC`. She would like to endeavor to construct a periodic string with length n(n≤20000) to spare her tedious time. In every period of the string, the substring begins with dozens of `A`s and ends with dozens of `C`s, and dozens of `B`s are inserted between them, and the number of `A`, `B`, `C` is a, b, c.(For example, if a=1, b=1, c=2 then one of the period of the string is `ABCC`, and the periodic string is `ABCCABCC……`).Note that in the last period of the string, the substring can be incomplete and the last few letters of the period can be cut down.

And now, Arabella has constructed a periodic string, she want to give you a question: if she tells you the character is Ci(Ci∈{A,B,C}) in the Xi(Xi≤10000) , then could you tell her the value of a,b,c? If there are multiple answers, please find the lexicographically smallest answer. If you can’t find a valid answer, please print `NO`
 

Input
The first line gives an integer T(1≤T≤40) , which indicates the number of cases in the input.
The first line of every case contains only one integer m(1≤m≤5000), which means the number of characters AraBella told you.
A number Xi(1≤Xi≤10000) and a letter Ci are given in the following m lines, which means the position Xi in the string with letter Ci.
 

Output
Print a,b,c in order. If there are multiple answers, please find the lexicographically smallest answer. If you can’t find a valid answer, please print `NO`.(It is gratuated that 0<a,b,c, and please forget my poor Yinglish)
 

Sample Input
2 3 1 A 2 B 3 C 4 1 A 2 C 3 B 4 C
 

Sample Output
1 1 1 NO
 

Source
 

Recommend
chendu
 

Statistic | Submit | Discuss | Note

分析

参照616156的题解。

题解又在卖萌了。。要用RMQ?。。。估计他自己没想清楚吧。。。这题哪用得着RMQ啊。。。

首先,可以暴力枚举循环节的长度:
然后,对每种字母进行判断,求出每个循环节中B,C最靠前的位置和A,B最靠后的位置。
如果A最靠后的位置在B最靠前的后面,或者B最靠后的位置在C最靠前的后面。就说明当前这个循环节长度是矛盾的。

如果不矛盾,则将A最靠后的位置及以前,都设为A,B最靠后的位置及以前(除去A的部分)都设为B,C则填充这个循环节剩余的位置。就能保证是当前长度循环节中,答案字典序最小一种方案。

问题就在于如何处理:“每个循环节中B,C最靠前的位置和A,B最靠后的位置”
可以利用调和级数:暴力枚举每个循环节,O(1)求出当前循环节最靠前的B、C,最靠后的A、B。总的时间复杂度就是O(N ln N)。

题解的方法说要用RMQ求这个问题。。。
其实就用前缀和后缀的思想不就行了?

对于每个点,它前面最近的一个A、B字母的位置,以及它后面最靠近的一个B、C字母的位置。这两个东西可以O(N)递推求出来

询问某个循环节时,求出其左端点及以后,最靠前的B、C,以及其右端点及以前最靠后的A、B即可(就是上面维护的那两个东西)。

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
using namespace std;
co int N=1e4;
int a[N+10],pre[N+10][4],las[N+10][4],ans[4],ans1[4];
char s[20];
int get_pre(int len,int x){
    int res=len;
    for(int i=1;i<=N;i+=len){
        int t=las[i][x];
        if(t>=i+len) continue;
        res=min(res,t-i+1);
    }
    return res;
}
int get_las(int len,int x){
    int res=0;
    for(int i=1;i<=N;i+=len){
        int top=min(i+len-1,N);
        int t=pre[top][x];
        if(t<i) continue;
        res=max(res,t-i+1);
    }
    return res;
}
int main(){
//  freopen(".in","r",stdin),freopen(".out","w",stdout);
    int kase=read<int>();
    while(kase--){
        int m=read<int>();
        memset(ans,-1,sizeof ans);
        memset(a,0,sizeof a);
        memset(pre,0,sizeof pre);
        memset(las,0x3f,sizeof las);
        for(int i=1,pos;i<=m;++i){
            read(pos);scanf("%s",s);
            a[pos]=s[0]-'A'+1;
        }
        for(int i=1;i<=N;++i)
            for(int j=1;j<=3;++j){
                if(a[i]==j) pre[i][j]=i;
                pre[i][j]=max(pre[i][j],pre[i-1][j]);
            }
        for(int i=N;i>=1;--i)
            for(int j=1;j<=3;++j){
                if(a[i]==j) las[i][j]=i;
                las[i][j]=min(las[i][j],las[i+1][j]);
            }
        for(int len=3;len<=N;++len){
            int lasx=0;
            bool flag=0;
            for(int j=1;j<=3;++j){
                if(j!=1){
                    int prex=get_pre(len,j);
                    if(prex<=lasx) {flag=1;break;}
                }
                if(j!=3){
                    lasx=max(lasx+1,get_las(len,j));
                    ans1[j]=lasx;
                }
                else ans1[j]=len;
            }
            if(flag==0){
                for(int j=1;j<=3;++j){
                    if(ans1[j]<ans[j]||ans[j]==-1){
                        ans[1]=ans1[1],ans[2]=ans1[2],ans[3]=ans1[3];
                        break;
                    }
                    if(ans1[j]>ans[j]) break;
                }
            }
        }
        if(ans[1]!=-1) printf("%d %d %d\n",ans[1],ans[2]-ans[1],ans[3]-ans[2]);
        else puts("NO");
    }
    return 0;
}

HDU6387 AraBellaC的更多相关文章

  1. 2018 Multi-University Training Contest 7 Solution

    A - Age of Moyu 题意:给出一张图,从1走到n,如果相邻两次走的边的权值不同,花费+1, 否则花费相同,求最小花费 思路:用set记录有当前点的最小花费有多少种方案到达,然后最短路 #i ...

随机推荐

  1. centos7: vsftpd安装及启动: ftp配置(以虚拟用户为例)

    centos7: vsftpd安装及启动: ftp配置 1安装: yum -y install vsftpd /bin/systemctl start vsftpd.service #启动 /bin/ ...

  2. SVN同步版本库与网站目录

    如何创建SVN版本库及同步文件到WEB目录 来源:空谷 一 安装与配置SVN 1.安装subversion centos: yum install subversion ubuntu: apt-get ...

  3. 牛客网暑期ACM多校训练营(第三场)DEncrypted String Matching fft

    题意:给你一个解密后的字符串,给你加密方式,加密过程可能出错,字符可能加减1,然后给你一个字符串,要求匹配个数(其实我也不太懂具体怎么加密解密,反正你把给你的前两个字符串用第三个加密一下,然后搞可以有 ...

  4. poj2686 状压dp入门

    状压dp第一题:很多东西没看懂,慢慢来,状压dp主要运用了位运算,二进制处理 集合{0,1,2,3,....,n-1}的子集可以用下面的方法编码成整数 像这样,一些集合运算就可以用如下的方法来操作: ...

  5. jquery添加类

    一.addClass() 方法向被选元素添加一个或多个类. 1.对P元素添加一个intro类.<!DOCTYPE html><html><head lang=" ...

  6. 62. 63. Unique Paths 64. Minimum Path Sum

    1. A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...

  7. 一篇分析诊断被&quot;hang&quot;住数据库的资料(Oracle Performance Diagnostic Guide——Hang/Locking)

    该资料已上传至本人QQ群空间,如需该资料,可到本人QQ群空间查找.下面贴表文本: Oracle Performance Diagnostic GuideHang/LockingVersion 3.1. ...

  8. DB2性能调优

    1.更新统计信息 --更新数据库所有表统计信息 --连接到数据库(-v选项,表示要回显命令,以下同) db2 -v connect to DB_NAME --查看是否收集过统计信息,什么时候更新的   ...

  9. pos提交提交数据时碰到Django csrf

    我的github(PS:希望star):https://github.com/thWinterSun/v-admin 最近在用Vue写前端代码,再用vue-resource向后台提交数据.项目后台是用 ...

  10. kill prefix out 1 homo,hemero out1

    1● homo 同性恋者     2●hetero 异性恋者