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; }