138. 兔子与兔子
#include <iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef unsigned long long ULL;
const int N = 1000010,base = 131;
ULL HASH[N], POW[N];
char str[N];
ULL getHash(int i, int j) {
return HASH[j] - HASH[i - 1] * POW[j - i + 1];
}
int main()
{
scanf("%s", str + 1);
int len = strlen(str + 1);
POW[0] = 1;
for (int i = 1; i <= len; i++) {
POW[i] = POW[i - 1] * base;
HASH[i] = HASH[i - 1] * base + str[i] - 'a';
}
int T;
cin>>T;
for(int cases=1;cases<=T;cases++){
int a,b,c,d;
cin>>a>>b>>c>>d;
if(getHash(a,b)==getHash(c,d))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
139. 回文子串的最大长度
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef unsigned long long ULL;
const int N=2000020,base=131;
ULL leftHash[N],rightHash[N];
ULL POW[N];
char str[N];
ULL getHash(int i,int j,ULL HASH[]){
return HASH[j]-HASH[i-1]*POW[j-i+1];
}
int main()
{
int T=1;
while(scanf("%s",str+1),strcmp(str+1,"END"))
{
int len=strlen(str+1);
for(int i=2*len;i>0;i-=2){
str[i]=str[i/2];
str[i-1]='#';
}
len*=2;
POW[0]=1;
for(int i=1,j=len;i<=len;i++,j--)
{
POW[i]=POW[i-1]*base;
leftHash[i]=leftHash[i-1]*base+str[i]-'a'+1;
rightHash[i]=rightHash[i-1]*base+str[j]-'a'+1;
}
int ans=0;
for(int i=1;i<=len;i++)
{
int l=0,r=min(i-1,len-i);
while(l<r)
{
int mid=(l+r+1)>>1;
//右起前缀数组索引与字符索引的映射关系
//1~n,2~n-1,...,i+1~n-i,i+mid~n+1-i-mid; (i+1,i+mid)~(n-i,n+1-i-mid)
if(getHash(i-mid,i-1,leftHash)!=getHash(len+1-i-mid,len-i,rightHash))
r=mid-1;
else
l=mid;
}
if (str[i - l] <= 'z' && str[i-l]>='a')
ans = max(ans, l + 1);
else
ans = max(ans, l);
scanf("%d",ans);
}
printf("Case %d: %d\n",T++,ans);
}
return 0;
}
140. 后缀数组
#include<iostream>
#include<algorithm>
#include<limits.h>
#include<string.h>
using namespace std;
typedef unsigned long long ULL;
const int N=300010,base=131;
ULL POW[N],HASH[N];
char str[N];
int n;
int suffix[N];
ULL getHash(int i,int j){
return HASH[j]-HASH[i-1]*POW[j-i+1];
}
int getLongestCommonPrefix(int i,int j){
int l=0,r=min(n-i+1,n-j+1);
while(l<r){
int mid=(l+r+1)>>1;
if(getHash(i,i+mid-1)!=getHash(j,j+mid-1))
r=mid-1;
else
l=mid;
}
return l;
}
bool compare(int a,int b){
int len=getLongestCommonPrefix(a,b);
int a1=a+len>n?INT_MIN:str[a+len];
int b1=b+len>n?INT_MIN:str[b+len];
return a1<b1;
}
int main(){
scanf("%s",str+1);
n=strlen(str+1);
POW[0]=1;
for(int i=1;i<=n;i++){
POW[i]=POW[i-1]*base;
HASH[i]=HASH[i-1]*base+str[i]-'a'+1;
suffix[i]=i;
}
sort(suffix+1,suffix+n+1,compare);
for(int i=1;i<=n;i++)
printf("%d ",suffix[i]-1);
printf("\n");
for(int i=1;i<=n;i++){
if(i==1)
printf("0 ");
else
{
printf("%d ",getLongestCommonPrefix(suffix[i-1],suffix[i]));
}
}
return 0;
}
137. 雪花雪花雪花
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=100010;
int snows[N][6];
int idx[N];
int snow[6],isnow[6];
int n;
bool cmpByArray(int a[],int b[])
{
for(int i=0;i<6;i++){
if(a[i]<b[i])
return true;
else if(a[i]>b[i])
return false;
}
return false;
}
bool comparator(int a,int b)
{
return cmpByArray(snows[a],snows[b]);
}
void getMinString(int* arr) //求解某个序列的最小字符串表示
{
static int a[12];
for (int i = 0; i < 12; i ++ )
a[i] = arr[i % 6];
int i = 0, j = 1, k;
while (i < 6 && j < 6)
{
for (k = 0; k < n && a[i + k] == a[j + k]; k ++ );
if (k == 6) break;
if (a[i + k] > a[j + k])
{
i += k + 1;
if (i == j) i ++ ;
}
else
{
j += k + 1;
if (i == j)
j ++ ;
}
}
k = min(i, j);
for (i = 0; i < 6; i ++ )
arr[i] = a[i + k];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=0;j<6;j++)
{
cin>>snow[j];
isnow[5-j]=snow[j];
}
getMinString(snow);
getMinString(isnow);
if(cmpByArray(snow,isnow))
memcpy(snows[i], snow, sizeof snow);
else
memcpy(snows[i], isnow, sizeof isnow);
idx[i]=i;
}
sort(idx+1,idx+1+n,comparator);
bool flag=false;
for(int i=2;i<=n;i++)
{
if(!cmpByArray( snows[idx[i-1]],snows[idx[i]] ) && !cmpByArray( snows[idx[i]],snows[idx[i-1]] ))
{
flag=true;
break;
}
}
if(flag)
cout<<"Twin snowflakes found."<<endl;
else
cout<<"No two snowflakes are alike."<<endl;
return 0;
}
136. 邻值查找
#include <iostream>
#include <limits.h>
#include <set>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
set<PII> record;
const int N=100010;
int arr[N];
int main(){
int n;
scanf("%d",&n);
cin>>arr[1];
record.insert({INT_MIN,0});
record.insert({INT_MAX,0});
record.insert({arr[1],1});
int i=2;
while(i<=n){
cin>>arr[i];
auto right=record.lower_bound({arr[i],i});
LL val=INT_MAX,index=-1;
if(right!=record.end())
{
val=min(val,right->first-(LL)arr[i]);
index=right->second;
}
if(right!=record.begin()){
right--;
if(arr[i]-(LL)right->first<val){
val=arr[i]-(LL)right->first;
index=right->second;
}
else if(arr[i]-(LL)right->first==val){
if(arr[right->second]<arr[index])
{
index=right->second;
}
}
}
cout<<val<<" "<<index<<endl;
record.insert({arr[i],i});
i++;
}
return 0;
}