博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #313 (Div. 1) B. Equivalent Strings
阅读量:6968 次
发布时间:2019-06-27

本文共 1942 字,大约阅读时间需要 6 分钟。

Equivalent Strings 

Problem's Link:


 

Mean: 

给定两个等长串s1,s2,判断是否等价。

等价的含义为:

若长度为奇数,则必须是相同串。

若长度是偶数,则将两串都均分成长度为原串一半的两个子串l1,r1和l2,r2,其中l1和l2等价且r1和r2等价,或者l1和r2等价且l2和r1等价。

analyse:

直接按照题意模拟写个递归分治就行。

比赛的时候总觉得这样暴力写会TLE,因为算了下大概是4^(log2(n))的复杂度,也就是n^2,所以比赛的时候就想了下,将两个串都按照题意转化为字典序最小串(循环节的最小表示法)然后比较a和b的两个最小表示法是否是相同的即可。
后来想了半天为什么分治到不了4^(log2(n))的复杂度呢?
原因是这样的:我们就按照这个复杂度去构造串。首先,如果要让al和ar比较,bl和br比较,且al和br也比较,ar和bl也比较的话,则必须满足al和bl等价,ar和br不等价,且al和br等价,这样才能保证让ar和bl去比较。然而我们在比较的al和bl的时候,再分治,设al分成了all,alr,bl分成了bll,blr,要想让它再比较4次,则有all和bll等价,alr和blr不等价,alr和bll等价,但因为这个情况下al和bl是等价的,所以必须有alr和bll等价。我们简单的写成
  all = bll
  alr != blr
  alr = bll
  all = blr
然而这4个等式可以推出all = bll = alr = blr,即4个子串任意都能等价,与第二个等式矛盾。这说明无法构造一种串使得复杂度达到4^(log2(n))。实际上,在很多时候递归只进行了三次甚至两次一次就返回了。因此分治的效率也是很高的。当然,最小表示法的复杂度是O(n*log(n))的,那是一定可以过。实际上还是分治的思想,只不过处理上有点不同罢了。

 

Time complexity: O(N*logN)

 

Source code: 

/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-07-22-22.45
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define  LL long long
#define  ULL unsigned long long
using
namespace
std;
#define NN 200000+50
char
A
[NN
], B
[NN
];
int
cmp(
char
x
[]
,
char
y
[]
,
int
len )
{
     
for(
int
i
=
0;
i
<
len;
++
i )
           
if(
x
[
i
]
<
y
[
i
] )
return
-
1;
           
else
if(
x
[
i
]
>
y
[
i
] )
return
1;
}
void
work(
int
len
,
char
x
[] )
{
     
if(
len
%
2
==
1 )
return ;
     
work(
len
/
2
,
x );
     
work(
len
/
2
,
x
+
len
/
2 );
     
if(
cmp(
x
,
x
+
len
/
2
,
len
/
2 )
>
0 )
           
for(
int
i
=
0;
i
<
len
/
2;
++
i )
                 
swap(
x
[
i
],
x
[
i
+
len
/
2
] );
}
int
main()
{
     
ios_base
::
sync_with_stdio(
false );
     
cin
.
tie(
0 );
     
scanf(
"%s %s"
,
A
, B );
     
int
len
=
strlen(
A );
     
work(
len
, B );
     
work(
len
,
A );
     
if(
strcmp(
A
, B )
==
0 )
puts(
"YES" );
     
else
puts(
"NO" );
     
return
0;
}
/*
*/

 

转载地址:http://dnisl.baihongyu.com/

你可能感兴趣的文章
Activiti系列: 如何添加自定义表单引擎
查看>>
Codeforces Round #332 (Div. 2) B. Spongebob and Joke 水题
查看>>
httpd/php/mysql的安装-1
查看>>
终极版:由简单工厂模式,升级到抽象工厂模式(用到反射)
查看>>
LintCode: O(1) Check Power of 2
查看>>
sysbench 测试MYSQL
查看>>
putty如何退出全屏模式
查看>>
c# 异步编程demo (async await)
查看>>
命令行參数选项处理:getopt()及getopt_long()函数使用
查看>>
OSS设置CORS规则以后还是报No 'Access-Control-Allow-Origin'解决方法
查看>>
opengl 教程(24) shadow mapping (2)
查看>>
数据库——浅谈数据库中的存储过程(转)
查看>>
html学习一(html简史及doctype)
查看>>
Castle IOC容器与Spring.NET配置之比较
查看>>
[Javascript] Call Stack
查看>>
单表60亿记录等大数据场景的MySQL优化和运维之道
查看>>
Linux zip解压/压缩并指定目录
查看>>
Ubuntu下安装MySQL 5.6.23
查看>>
Codeforces Round #261 (Div. 2)——Pashmak and Buses
查看>>
kafka源码分析之一server启动分析
查看>>