BZOJ3916: [Baltic2014]friends

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3916

复习一下hash(然后被傻叉错误卡了半天TAT。。。

取出一个字串:h[r]-h[l-1]*power[r-l+1]  然后匹配。。。

注意一下当前需要的是s[i]还是s[i-1],做hash数组时不要写s[i]-'A',写s[i],否则容易被卡

对于这道题,枚举一下断点,注意判重。

对于这种有断点的前面一段+后面一段等于完整一段,要注意前面那一段乘的权。

#include<cstring>
#include<iostream>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define maxn 2000009
#define p 23333
using namespace std;
typedef unsigned long long ll;
char ans[maxn],s[maxn];
ll h[maxn],bin[maxn],last;
int now,n,mid,anspos;
int read(){
    int x=0,f=1; char ch=getchar();
    while (!isdigit(ch)){
        if (ch=='-') f=-1; ch=getchar();
    }
    while (isdigit(ch)){
        x=x*10+ch-'0'; ch=getchar();
    }
    return x*f;
}
ll get(int l,int r){
    return h[r]-h[l-1]*bin[r-l+1];
}
int judge(int pos){
    ll x,y,z;
    int flag=0;
    if (pos<mid){
        x=get(1,pos-1)*bin[mid-pos]+get(pos+1,mid);
        y=get(mid+1,n);
    }
    else if (pos>mid){
        x=get(1,mid-1);
        y=get(mid,pos-1)*bin[n-pos]+get(pos+1,n);
    }
    else if (pos==mid){
        x=get(1,mid-1);
        y=get(mid+1,n);
    }
    if (x==y){
        if (x==last) return 0;
        last=x;
        int top=0;
        if (pos<=mid) rep(i,mid+1,n) ans[++top]=s[i];
        else rep(i,1,mid-1) ans[++top]=s[i];
        return 1;
    }
    return 0;
}
int main(){
    n=read(); if (n%2==0) {puts("NOT POSSIBLE"); return 0;}
    scanf("%s",s+1); 
    bin[0]=1; rep(i,1,n) bin[i]=bin[i-1]*p;
    rep(i,1,n) h[i]=h[i-1]*p+s[i];
    mid=(n/2)+1;
    int cnt=0;
    rep(i,1,n) {
        cnt+=judge(i);
        if (cnt>1) break;
    }
    if (!cnt) puts("NOT POSSIBLE");
    else if (cnt>1) puts("NOT UNIQUE");
    else puts(ans+1);
    return 0; 
}

 

posted on 2015-11-26 20:49  ctlchild  阅读(698)  评论(0编辑  收藏  举报

导航