HDU6387 AraBellaC
题意
AraBellaC
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 277 Accepted Submission(s): 100
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`
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.
2 3 1 A 2 B 3 C 4 1 A 2 C 3 B 4 C
1 1 1 NO
分析
参照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的更多相关文章
- 2018 Multi-University Training Contest 7 Solution
A - Age of Moyu 题意:给出一张图,从1走到n,如果相邻两次走的边的权值不同,花费+1, 否则花费相同,求最小花费 思路:用set记录有当前点的最小花费有多少种方案到达,然后最短路 #i ...
随机推荐
- [.NET开发] C#实现剪切板功能
C#剪切板 Clipboard类 我们现在先来看一下官方文档的介绍 位于:System.Windows.Forms 命名空间下 Provides methods to place data on an ...
- (转)不要自称是程序员,我十多年的 IT 职场总结
其他: 我是一名程序员,工作很努力,为什么绩效还总是垫底? 外企,中年失业何去何从? 来公司半年了,也悟出了一些道理. 如果我可以给每个工程教育增加一门课,它不会涉及编译器.门电路或是时间复杂度,而是 ...
- Android之MVP模式实现登录和网络数据加载
MVP简介 相信大家对 MVC 都是比较熟悉了:M-Model-模型.V-View-视图.C-Controller-控制器,MVP作为MVC的演化版本,也是作为用户界面(用户层)的实现模式,那么类似的 ...
- 『PyTorch』第三弹重置_Variable对象
『PyTorch』第三弹_自动求导 torch.autograd.Variable是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现 Varibale包含三个属性: data ...
- python-day17--列表推导式,生成器表达式
# for i in range(100):# print(i*i) 列表推导式: # l =[i*i for i in range(100)]# print(l) # l = [{'name':'v ...
- hdu-6324-博弈
Problem F. Grab The Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Ja ...
- JavaScript运算符:递增递减运算符前置和后置的区别
从两段代码说起 var num1 = 2; var num2 = 20; var num3 = --num1 + num2; var num4 = num1 + num2; console.log(n ...
- 如何使用Java Enum
简单的用法:JavaEnum简单的用法一般用于代表一组常用常量,可用来代表一类相同类型的常量值.如: 性别: public enum SexEnum { male, female; } 颜色: pub ...
- beaglebone-black reference url
reference : https://github.com/beagleboard/beaglebone-black/wiki/System-Reference-Manual https://bea ...
- 玩转X-CTR100 l STM32F4 l CAN通信
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] X-CTR100控制器STM32F4处理器内置CAN ...