题意

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. wpf里窗体嵌入winform控件被覆盖问题

      问题1:嵌套Winform控件(ZedGraph)在WPF的ScrollViewer控件上,出现滚动条,无论如何设置该Winform控件都在顶层,滚动滚动条会覆盖其他WPF控件. 解决办法:在Sc ...

  2. English trip -- VC(情景课)1 C What's your name?

    Grammar focus 语法点 What's your name? What's his name? What her name? My name is Angela. His name is K ...

  3. Jmeter响应中中文乱码解决办法

    在jmeter的bin目录下有一个jmeter.properties的文件,打开它,搜索sampleresult.default.encoding,把它的注释打开,也就是把最前面的#去掉,改成samp ...

  4. python-day8-元组的内置方法

    #为何要有元组,存放多个值,元组不可变,更多的是用来做查询# t=(1,[1,3],'sss',(1,2)) #t=tuple((1,[1,3],'sss',(1,2)))# print(type(t ...

  5. ScoketTimeout Exception浅析

    以前都是用WebService的方式调用服务方的服务,此次直接调用别人的http服务. 使用的客户端是org.apache.http.client.HttpClient. 用的httpclient-4 ...

  6. vEthernet(默认交换机) 无法访问网络

    VMware 开启虚拟机 最近公司由无线网转为有线时,我用VMware Workstation Pro装的几个系统,其中一个 ubuntu无法访问网页,在ubuntu运行ifconfig -a ,直接 ...

  7. dup的使用(二)

    转自:http://blog.csdn.net/yeyuangen/article/details/6852682 一个进程在此存在期间,会有一些文件被打开,从而会返回一些文件描述符,从shell中运 ...

  8. httpclient cookie相关介绍

    http状态管理 cookie是HTTP代理和目标服务器可以交流保持回话的状态信息的令牌或短包. httpclient使用Cookie接口来代表抽象的cookie令牌,在它的简单形式中http的coo ...

  9. apscheduler -定时任务

    https://apscheduler.readthedocs.io/en/latest/userguide.html 简单的使用方式为: from apscheduler.schedulers.bl ...

  10. C++设计模式之访问者模式

    简述 访问者模式(Visitor Pattern)表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 代码实现: // Visitor.cpp : ...