首页 > 其他分享 >hdu 5442 长春区域赛网络赛 1006 Favorite Donut(后缀数组)

hdu 5442 长春区域赛网络赛 1006 Favorite Donut(后缀数组)

时间:2023-04-23 21:37:01浏览次数:47  
标签:hdu int 5442 Favorite sufix -- maxn ans include


题目链接:

hdu 5442


题目大意:

给出一个环,每颗珠子有一个甜度,选择第一个珠子和吃的方向,问得到的吃珠子的字符串的字典序最大的,如果有多个,选取位置最靠前的,如果还是多个,选择顺时针吃的。


题目分析:

-首先构造一个字符串,首先正着按环吃,那么就是字符串正着写两遍,连接在一起;中间用没有出现过的字符连接,然后逆时针吃的,也就是反着写两遍连在一起。
- 然后我们找到后缀排序前面与排序第一个的公共前缀大于等于n的所有的情况,然后寻找他们当中符合题意的字符串的即可。起始位置可以通过suffix数组得到。


AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 200007
int wwa[maxn],wwb[maxn],wwv[maxn],wws[maxn];
int cmp(int *r,int a,int b,int l){
    return r[a]==r[b]&&r[a+l]==r[b+l];
}

void da(int *r,int *sufix,int n,int m){
    int i,j,p,*x=wwa,*y=wwb,*t;
    for(i=0;i<m;i++)wws[i]=0;
    for(i=0;i<n;i++)wws[x[i]=r[i]]++;
    for(i=1;i<m;i++)wws[i]+=wws[i-1];
    for(i=n-1;i>=0;i--)sufix[--wws[x[i]]]=i;
    for(j=1,p=1;p<n;j*=2,m=p){
        for(p=0,i=n-j;i<n;i++)y[p++]=i;
        for(i=0;i<n;i++)
            if(sufix[i]>=j)
                y[p++]=sufix[i]-j;
        for(i=0;i<n;i++)wwv[i]=x[y[i]];
        for(i=0;i<m;i++)wws[i]=0;
        for(i=0;i<n;i++)wws[wwv[i]]++;
        for(i=1;i<m;i++)wws[i]+=wws[i-1];
        for(i=n-1;i>=0;i--)
            sufix[--wws[wwv[i]]]=y[i];
        for(t=x,x=y,y=t,p=1,x[sufix[0]]=0,i=1;i<n;i++)
            x[sufix[i]]=cmp(y,sufix[i-1],sufix[i],j)?p-1:p++;

    }
    return;
}
int r[maxn];
int rank1[maxn],height[maxn],sufix[maxn];
void calheight(int *r,int *sufix,int n){
    int i,j,k=0;
    for(i=0;i<=n;i++) rank1[sufix[i]]=i;
    for(i=0;i<n;height[rank1[i++]]=k)
        for(k?k--:0,j=sufix[rank1[i]-1];r[i+k]==r[j+k];k++);
    return;
}
struct Node{
    int p,c;
};
int comp(Node a,Node b){
    if(a.p == b.p) return a.c < b.c;
    return a.p < b.p;
}

Node ans[maxn];

char word[maxn];

int main(){
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        scanf("%s",word);
        for(int i = 0;i < n; i++){
            r[i]=r[i+n] = word[i];
        }
        int len =n*4+1;
        r[n*2] = '#';
        for(int i = 0;i < n; i++){
            r[i+n*2+1] = r[i+n*3+1] = word[n-i-1];
        }
        r[len] = 0;
        da(r,sufix,len+1,328);
        calheight(r,sufix,len);
        int cnt = 0;
        ans[cnt++].p = sufix[len];
        for(int i = len-1;i > 1; i--){
            if(height[i+1] < n) break;
            if(sufix[i]>=n&&sufix[i]<=n*2) continue;
            if(sufix[i]>=n*3+1)continue;
            ans[cnt++].p = sufix[i];
        }
        for(int i = 0;i < cnt; i++){
            if(ans[i].p > 2*n){
                ans[i].c =1;
                ans[i].p = n-(ans[i].p-2*n-1);
            }
            else {
                ans[i].p++;
                ans[i].c =  0;
            }
        }
        sort(ans,ans+cnt,comp);
        printf("%d %d\n",ans[0].p,ans[0].c);
    }
    return 0;
}


标签:hdu,int,5442,Favorite,sufix,--,maxn,ans,include
From: https://blog.51cto.com/u_7936627/6218745

相关文章

  • hdu 5446 长春区域赛网络赛1010 Unknown Treasure(lucas定理+中国剩余定理+移位乘法)
    题目链接:hdu5446题目大意:求出Cmn%M,M=p1⋅p2⋯pk题目分析:首先对于每个质数pi我们,我们可以利用Lucas定理求出Cmn%pi的值,Lucas定理如下:Cmn%p=Cm/pn/p⋅Cm%pn%p%p然后我们可以利用中国剩余定理求取最后答案:M=∏i=1kpi,Mi=M/piCmn%M=∑i=1kCmn%pi⋅Mi⋅inv[Mi]因为做乘法......
  • hdu 5444 长春区域赛网络赛 1008 Elven Postman(模拟)
    题目链接:hdu5444题目大意:给出一个序列,这个序列的第一个点是树的根节点,每次操作从当前点走到当前最靠右的每走过的点(点的序号越小越靠右),问将物品从根送到某个点的行进路线.题目分析:个人认为难在题意。。。构造出这个树之后,直接从目的地走回根节点就可以得到要求的路径。然后如何构......
  • HDU 5389 Zero Escape(DP + 滚动数组)
    ZeroEscapeTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:131072/131072K(Java/Others)TotalSubmission(s):864    AcceptedSubmission(s):438ProblemDescriptionZeroEscape,isavisualnoveladventurevideogamedirectedbyKotar......
  • HDU1873 看病要排队
    E- 看病要排队TimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uDescription看病要排队这个是地球人都知道的常识。不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么......
  • HDU 1114 Piggy-Bank
    F- Piggy-BankTimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uSubmit StatusDescriptionBeforeACMcandoanything,abudgetmustbepreparedandthenecessaryfinancialsupportobtained.Themaininc......
  • HDU 1869 六度分离
    六度分离TimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uSubmit Status Practice HDU1869Description1967年,美国著名的社会学家斯坦利・米尔格兰姆提出了一个名为“小世界现象(smallworldphenom......
  • HDU 1527 取石子游戏(博弈论)
    取石子游戏TimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/32768K(Java/Others)TotalSubmission(s):3717    AcceptedSubmission(s):1868ProblemDescription有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有......
  • kuangbin专题一 简单搜索 石油储备(HDU-1241)
    OilDepositsTimeLimit:2000/1000MS(Java/Others)MemoryLimit:65536/32768K(Java/Others)ProblemDescriptionTheGeoSurvCompgeologicsurveycompanyisresponsiblefordetectingundergroundoildeposits.GeoSurvCompworkswithonelargerectangula......
  • HDU 1042 N! (大整数阶乘)
    这道题开始并不会,是看了别人的代码,自己又改造了一下,代码如下:(PS:这个时候自带大整数运算的java就有优势了)#include<bits/stdc++.h>usingnamespacestd;constintN=20000+10;intans[N];voidfact(intn){ans[0]=ans[1]=1;inttot=1;for(inti=......
  • HDU 1253 胜利大逃亡
    题目有个坑是可能没有到达门口的路,结果WA好几次#include<iostream>#include<cstdio>#include<queue>#include<algorithm>usingnamespacestd;constintINF=10000000;inta,b,c,d;ints[60][60][60],cost[60][60][60];intdx[]={0,0,1,-1,0,0}......