CF1037H Security(SAM)
生活随笔
收集整理的這篇文章主要介紹了
CF1037H Security(SAM)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
解析
算是一個比較高級的SAM的應用了
對fail樹的dfs序建立維護右端點最大值的線段樹
考慮把所有的詢問離線,按照右端點排序
每次動態把當前詢問右端點左側的前綴插入線段樹
處理詢問時,先貪心的嘗試和詢問串填法一樣,如果不行就往下一個字母填
判斷合法的標志就是左端點的最大值是否不小于詢問的左端點
代碼
#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) const int N=2e5+100; inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } int n,m; struct node{int len,fa;int tr[26]; }st[N]; int tot(1),lst(1),id[N]; void ins(int c,int ide){c-='a';int cur=++tot,p=lst;lst=tot;st[cur].len=st[p].len+1;id[ide]=cur;for(;p&&!st[p].tr[c];p=st[p].fa) st[p].tr[c]=cur;if(!st[p].tr[c]) st[cur].fa=1;else{int q=st[p].tr[c];if(st[q].len==st[p].len+1) st[cur].fa=q;else{int pp=++tot;st[pp]=st[q];st[pp].len=st[p].len+1;st[q].fa=st[cur].fa=pp;for(;p&&st[p].tr[c]==q;p=st[p].fa) st[p].tr[c]=pp;return;}} }struct #define mid ((l+r)>>1) #define ls (k<<1) #define rs (k<<1|1) segment_tree{int mx[N<<2];int ask(int k,int l,int r,int x,int y){if(x<=l&&r<=y) return mx[k];int res=0;if(x<=mid) res=max(res,ask(ls,l,mid,x,y));if(y>mid) res=max(res,ask(rs,mid+1,r,x,y)); //if(k==1) printf("---ask: (%d %d) res=%d\n",x,y,res);return res;}void upd(int k,int l,int r,int p,int w){//if(k==1) printf("---upd: p=%d w=%d\n",p,w);if(l==r){mx[k]=max(mx[k],w);return;}if(p<=mid) upd(ls,l,mid,p,w);else upd(rs,mid+1,r,p,w);mx[k]=max(mx[ls],mx[rs]);return;} }t;string s,ss,ask[N],ans[N]; struct query{int id,l,r,len;bool operator < (const query o)const{return r<o.r;} }q[N]; int St[N],tim,Ed[N]; vector<int>v[N]; void dfs(int x){St[x]=++tim;for(const auto &to:v[x]) dfs(to);Ed[x]=tim;return; } bool jd[N]; inline bool check(int x,int l,int len){//printf(" check:x=%d l=%d len=%d ask=%d\n",x,l,len,t.ask(1,1,tim,St[x],Ed[x]));return t.ask(1,1,tim,St[x],Ed[x])-len+1>=l; } bool find(int x,int len,int o,int idx){if(len>q[idx].len){for(int i=0;i<=25;i++){if(st[x].tr[i]&&check(st[x].tr[i],q[idx].l,len)){jd[o]=1;ans[o]+='a'+i;//printf("ok x=%d to=%d\n",x,st[x].tr[i]);return true;}}return false;} int c=ask[o][len]-'a';//printf("x=%d len=%d c=%d\n",x,len,c);if(st[x].tr[c]&&check(st[x].tr[c],q[idx].l,len)&&find(st[x].tr[c],len+1,o,idx)){ans[o]+='a'+c;return true;}else{for(int i=c+1;i<=25;i++){ if(st[x].tr[i]&&check(st[x].tr[i],q[idx].l,len)){//printf("?? o=%d ask=%d len=%d\n",o,t.ask(1,1,tim,St[st[x].tr[i]],Ed[st[x].tr[i]]),len);jd[o]=1;ans[o]+='a'+i;return true;}}return false;} } signed main(){ #ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout); #endifcin>>s;s.insert(s.begin(),' ');n=s.size()-1;for(int i=1;i<=n;i++) ins(s[i],i);for(int i=2;i<=tot;i++) v[st[i].fa].push_back(i);dfs(1);//for(int i=1;i<=tot;i++) printf("i=%d fa=%d (%d %d)\n",i,st[i].fa,St[i],Ed[i]);m=read();for(int i=1;i<=m;i++){q[i].l=read();q[i].r=read();q[i].id=i;cin>>ask[i];ask[i].insert(ask[i].begin(),' ');//if(i==75){//printf("(%d %d) ",q[i].l,q[i].r);cout<<ask[i]<<endl;//}q[i].len=ask[i].size()-1;}sort(q+1,q+1+m);int pl=0;for(int i=1;i<=m;i++){while(pl<q[i].r){++pl;t.upd(1,1,tim,St[id[pl]],pl);//printf("upd: node=%d pos=%d\n",id[pl],St[id[pl]]);}find(1,1,q[i].id,i);}for(int i=1;i<=m;i++){if(!jd[i]) printf("-1\n");else{for(int j=ans[i].size()-1;j>=0;j--) putchar(ans[i][j]);putchar('\n');}}return 0; } /* */總結
以上是生活随笔為你收集整理的CF1037H Security(SAM)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第二代The Freestyle三星随享
- 下一篇: 世界互联网发展指数排名发布:美国、中国领