HDU 5371 (2015多校联合训练赛第七场1003)Hotaru's problem(manacher+二分/枚举)

pid=5371">HDU 5371

题意:

定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分同样,第一部分与第二部分对称。

如今给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度。

思路:

来自官方题解:修正了一些题解错别字(误

先用求回文串的Manacher算法。求出以第i个点为中心的回文串长度。记录到数组p中

要满足题目所要求的内容。须要使得两个相邻的回文串,共享中间的一部分,也就是说。左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样。 由于我们已经记录下来以第i个点为中心的回文串长度, 那么问题能够转化成,相距x的两个数a[i],a[i+x],满足p[i]/2>=x 而且 p[i+x]/2>=x。要求x尽量大

这能够用一个set维护。一開始集合为空,依次取出p数组中最大的元素。将其下标放入set中,每取出一个元素,在该集合中二分查找比i+p[i]/2小,但最大的元素。更新ans。

然后查找集合中比i-p[i]/2大,但最小的元素,更新ans。

答案就是3*ans

嗯~事实上不用二分暴力扫下也能水过去

/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>

using namespace std;

#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;
const int maxn = 100000 + 5;
int p[2*maxn];
int s[maxn];
int s1[2*maxn];
int n;
void init(){
    cls(s1);
    s1[0] = -1;
    s1[1] = -2;
    int k = 2;
    for(int i = 0 ; i < n ; i++){
        s1[k++] = s[i];
        s1[k++] = -2;
    }
}

void manacher(){
    int mx = 0 , id = 0;
    p[0] = 0;
    for(int i = 0 ; i < 2*n+1 ; i++){
        if(mx > i) p[i] = min(p[2*id-i] , mx-i);
        else p[i] = 1;
        while(s1[i-p[i]] == s1[i+p[i]]) p[i]++;
        if(mx < p[i]+i){
            mx = p[i] + i;
            id = i;
        }
    }
}

int solve(){
    int ans = 0;
    for(int i = 1; i < n*2 + 1 ; i += 2)
        if((p[i] - 1) / 2 > ans){
            for(int j = i + p[i] - 1 ; ; j -= 2){
                if(p[j] >= j-i){
                    ans = (j-i) / 2;
                    break;
                }
                if((j-i)/2 <= ans)  break;
            }
        }
    return 3*ans;
}
int main(){
  //freopen("input.txt","r",stdin);
    int t; cin >> t ; int kase = 1;
    while(t--){
        cls(s);cls(p);cls(s1);
        cin >> n;
        for(int i = 0 ; i < n ; i++){
             scanf("%d",s+i);
        }
        init();
        manacher();
        printf("Case #%d: %d\n",kase++,solve());
    }
    return 0;
}

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru's problem(manacher+二分/枚举)

时间: 2024-10-11 05:11:35

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)的相关文章

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)

HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分相同,第一部分与第二部分对称. 现在给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法,求出以第i个点为中心的回文串长度,记录到数组p中 要满足题目所要求的内容,需要使得两个相邻的回文串,共享中间的一部分,也就是说,左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样. 因为我们已经记录下来以

hdu 5361 2015多校联合训练赛#6 最短路

In Touch Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 67    Accepted Submission(s): 11 Problem Description There are n soda living in a straight line. soda are numbered by  from left to ri

HDU 5358(2015多校联合训练赛1006) First One (区间合并+常数优化)

HDU 5358 题意: 求∑?i=1?n??∑?j=i?n??(?log?2??S(i,j)?+1)?(i+j). 思路: S(i,j) < 10^10 < 2^34,所以log2(S)+1的值只可能在1~35之间.由于log变化缓慢的函数特性,我们可以S(i,n)分作多个相同log值的区间来计算,用pos[i][j]预处理记录每个以i为起点,log(s)值为j的区间的右边界,即可优化至nlogn的复杂度. 主要是写起来比较难一些,一些细节比较纠结,一定思路理清后再写. ps.此题卡常数毫无

hdu 5358 First One 2015多校联合训练赛#6 枚举

First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 142    Accepted Submission(s): 37 Problem Description soda has an integer array a1,a2,-,an. Let S(i,j) be the sum of ai,ai+1,-,aj. No

hdu 5381 The sum of gcd 2015多校联合训练赛#8莫队算法

The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 23    Accepted Submission(s): 4 Problem Description You have an array ,the length of  is Let Input There are multiple test cases.

hdu 5288||2015多校联合第一场1001题

http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a array A of size n ,defined a function f(l,r) represent the number of i (l<=i<=r) , that there's no j(l<=j<=r,j<>i) satisfy ai mod aj=0,now OO want to know ∑i

HDU 5371(2015多校7)-Hotaru&#39;s problem(Manacher算法求回文串)

题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列,该子序列分为三部分,第一部分与第三部分相同,第一部分与第二部分对称,如果存在求最长的符合这种条件的序列. 思路:用Manacher算法来处理回文串的长度,记录下以每一个-1(Manacher算法的插入)为中心的最大回文串的长度.然后从最大的开始穷举,只要p[i]-1即能得出以数字为中心的最大回文串的长度,然后找到右边对应的'-1',判断p[i]是不是大于所穷举的长度,如果当前的满足三段,那么就跳出,继续

HDU 4941 Magical Forest(map映射+二分查找)杭电多校训练赛第七场1007

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 解题报告:给你一个n*m的矩阵,矩阵的一些方格中有水果,每个水果有一个能量值,现在有三种操作,第一种是行交换操作,就是把矩阵的两行进行交换,另一种是列交换操作,注意两种操作都要求行或列至少要有一个水果,第三种操作是查找,询问第A行B列的水果的能量值,如果查询的位置没有水果,则输出0. 因为n和m都很大,达到了2*10^9,但水果最多一共只有10^5个,我的做法是直接用结构体存了之后排序,然后m

UPC2018组队训练赛第七场

题目来自ICPC 2017 Japan Tsukuba A题:Secret of Chocolate Poles 有三种巧克力,分别是厚度为1的白色巧克力,厚度为1或者k的黑色巧克力.要求把巧克力放到高度为 l 的盒子里,并且要黑白相间,底部和顶部必须都是黑色的 当l=1,ans=1:当l<k,ans=(l-1)/2+1:当l=k,ans=(l-1)/2+2;当l>k时,就可以转化成排列组合问题了,枚举厚度为k的黑色巧克力数目i,然后对于每一种情况,再枚举厚度为1的黑色巧克力的数目j,那么此时