题意

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. 谈谈Java反射机制

    原文出处: locality 写在前面:什么是java反射机制?我们又为什么要学它?当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.我们认为java并不是动态语言,但是它却有一个非常突 ...

  2. python-day47--mysql数据备份与恢复

    一.IDE工具介绍 掌握: #1. 测试+链接数据库 #2. 新建库 #3. 新建表,新增字段+类型+约束 #4. 设计表:外键 #5. 新建查询 #6. 备份库/表 #注意: 批量加注释:ctrl+ ...

  3. Oracle性能诊断艺术-学习笔记(索引访问方式)

    环境准备: 1.0 测试表 CREATE TABLE t ( id NUMBER, d1 DATE, n1 NUMBER, n2 NUMBER, n3 NUMBER, n4 NUMBER, n5 NU ...

  4. Leetcode 77

    //这似乎是排列组合的标准写法了已经class Solution { public: vector<vector<int>> combine(int n, int k) { v ...

  5. ADO.NET 体系结构

    两个部分 .NET 数据提供者 DataSet 数据提供者 SqlClient 提供者 OleDb 提供者 Odbc 提供者 数据提供者组件 数据对象 DataSet

  6. 浏览器请求中文乱码(ISO-8859-1 to UTF-8)

    String utfString=new String(param.getBytes("iso-8859-1"),"utf-8");

  7. python dict 构造函数性能比较

    from time import time t1 = time() {i: "%d" % i for i in range(5000)} t2 = time() print(t2- ...

  8. MySQL查询性能优化---高性能(二)

    转载地址:https://segmentfault.com/a/1190000011330649 避免向数据库请求不需要的数据 在访问数据库时,应该只请求需要的行和列.请求多余的行和列会消耗MySql ...

  9. jsoupa-解析遍历一个HTML

    解析个遍历一个HTML文档 String html ="<html><head><title>First parse</title></ ...

  10. storage路径问题

    1 概念总述 android开发中,关于存储路径,我们经常听到以下几个概念:内存.内部存储和外部存储,现在我们就来详细说说这三者区别与联系. 内存:英文中记为memory,即RAM 内部存储:英文记为 ...