1. 程式人生 > >2016 全國多校第二場 訓練日誌

2016 全國多校第二場 訓練日誌

出現 LV main red IE cpe https 標記 href

solve 4 (131/582)

A Acperience (解方程)

E Eureka (幾何點對相關)

I It‘s All In The Mind (簽到)

K Keep On Movin (簽到)

L La Vie en rose (字符串hash)

<qj>

思路:

正解可能是dp之類的,用hash字符串水了出來。

1.對於t串,hash成一個數字。                 復雜度O(|t|)

2.對s進行一次滾動hash。                  復雜度O(|s|)

3.

對於截取的一段ss,如果ss的hash值等於t的hash值,那麽直接輸出1;        復雜度O(1)

對於截取的一段ss,如果這個值以前用過,如果標記為1,那麽輸出1,否則輸出0;   復雜度O(1)

對於截取的一段ss,如果沒出現過,暴力跑一次,並且輸出,然後標記。        復雜度O(|t|)

對於第三步的第三種情況,很難造出這種數據的,所以,復雜度可接受。

代碼:

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;

unordered_map<ull,int> mp;

int n,m;
char s[100005],t[5005];
int lens,lent;

ull 
base = 131; ull po[100105],hs[100005]; ull geth(int l,int r){ return (ull)hs[r]-po[r-l+1]*hs[l-1]; } int main(){ po[0]=1; for(int i=1;i<=100000;i++){ po[i]=po[i-1]*base; } int T;cin>>T; while(T--){ mp.clear(); scanf("%d%d",&n,&m); scanf(
"%s%s",s+1,t+1); lens=strlen(s+1);lent=strlen(t+1); ull tt=0; for(int i=1;i<=lent;i++) tt=tt*base+(ull)t[i]; for(int i=1;i<=lens;i++){ hs[i]=hs[i-1]*base+s[i]; } for(int i=1;i<=lens-lent+1;i++){ ull ss = geth(i,i+lent-1); if(tt==ss){ printf("1");continue; } if(mp.find(ss)!=mp.end()){ if(mp[ss]==1)printf("1"); else printf("0"); continue; } bool ok=1; for(int j=1;j<=lent;j++){ if(s[i+j-1]==t[j])continue; if(j==lent){ ok=0;break; } if(t[j]==s[i+j] && t[j+1]==s[i+j-1]){ j++; } else { ok=0;break; } } if(ok){ printf("1");mp[ss]=1; } else { printf("0");mp[ss]=-1; } } for(int i=lens-lent+1;i<lens;i++)printf("0"); printf("\n"); } return 0; }

2016 全國多校第二場 訓練日誌