CF1037H. Security
CF1037H. Security
Solution 1
設(shè)原串為ststst。
對(duì)于單個(gè)詢問(wèn),答案必然是詢問(wèn)串sss的一個(gè)前綴s[1..i]s[1..i]s[1..i]加上一個(gè)大于s[i+1]s[i+1]s[i+1]的字符ccc構(gòu)成。
因此我們只需要枚舉前綴s[1..i]s[1..i]s[1..i],枚舉字符ccc,快速詢問(wèn)s[1..i]+cs[1..i]+cs[1..i]+c有沒(méi)有在st[l,r]st[l,r]st[l,r]中出現(xiàn)過(guò),后綴自動(dòng)機(jī)+線段樹合并,記錄區(qū)間內(nèi)存在的末尾位置個(gè)數(shù)即可。
時(shí)間復(fù)雜度O(26?nlgn)O(26*nlgn)O(26?nlgn)
Solution 2
我們發(fā)現(xiàn)我們用線段樹合并記錄區(qū)間末尾位置個(gè)數(shù)并不優(yōu),我們考慮直接記錄區(qū)間內(nèi)是否有ccc的可行轉(zhuǎn)移,因?yàn)樽址挥?span id="ze8trgl8bvbq" class="katex--inline">262626,我們可以把它壓成2262^{26}226的intintint,即可快速判斷是否可以轉(zhuǎn)移。
時(shí)間復(fù)雜度O((26+lgn)?n)O((26+lgn)*n)O((26+lgn)?n)
Code 1
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> #include <cassert> #include <string.h> //#include <unordered_set> //#include <unordered_map> //#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B) #define PB(A) push_back(A) #define SIZE(A) ((int)A.size()) #define LEN(A) ((int)A.length()) #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define fi first #define se second using namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; } template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll; typedef unsigned long long ull; typedef long double lod; typedef pair<int,int> PR; typedef vector<int> VI;const lod eps=1e-11; const lod pi=acos(-1); const int oo=1<<30; const ll loo=1ll<<62; const int mods=1e9+7; const int MAXN=400005; const int INF=0x3f3f3f3f;//1061109567 /*--------------------------------------------------------------------*/ inline int read() {int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f; } char St[MAXN],st[MAXN]; int ls[MAXN*20],rs[MAXN*20],s[MAXN*20],rt[MAXN],nw[MAXN],nodenum=0; void print(int x,int y) {for (int i=1;i<=x;i++) putchar(St[i]);putchar(y+'a');puts(""); }int query(int x,int l,int r,int L,int R) {if (L>R||!x) return 0;if (l>=L&&r<=R) return s[x];int mid=(l+r)>>1;if (R<=mid) return query(ls[x],l,mid,L,R);else if (L>mid) return query(rs[x],mid+1,r,L,R);else return query(ls[x],l,mid,L,mid)+query(rs[x],mid+1,r,mid+1,R); } int merge(int x,int y) {if (!x||!y) return x|y;int z=++nodenum;s[z]=s[x]+s[y];ls[z]=merge(ls[x],ls[y]);rs[z]=merge(rs[x],rs[y]);return z; } int update(int x,int l,int r,int y) {if (!x) x=++nodenum;s[x]++;if (l==r) return x;int mid=(l+r)>>1;if (y<=mid) ls[x]=update(ls[x],l,mid,y);else rs[x]=update(rs[x],mid+1,r,y); return x; }int t[MAXN][26],len[MAXN],fa[MAXN],Lst[MAXN],sz=2,lst=1; void insert(int c,int id) {int p=lst,np=lst=sz++;len[np]=len[p]+1,Lst[id]=np;for (;p&&!t[p][c];p=fa[p]) t[p][c]=np;if (!p) { fa[np]=1; return; }int q=t[p][c];if (len[q]==len[p]+1) fa[np]=q;else{int nq=sz++;fa[nq]=fa[q];fa[np]=fa[q]=nq;len[nq]=len[p]+1;memcpy(t[nq],t[q],sizeof t[0]);for (;t[p][c]==q;p=fa[p]) t[p][c]=nq;} } int c[MAXN]={1},a[MAXN]; void Init() {for (int i=1;i<sz;i++) c[i]=0;for (int i=1;i<sz;i++) c[len[i]]++;for (int i=1;i<sz;i++) c[i]+=c[i-1];for (int i=sz-1;i>=1;i--) a[--c[len[i]]]=i;for (int i=sz-1;i>=1;i--) rt[fa[a[i]]]=merge(rt[fa[a[i]]],rt[a[i]]); } signed main() {scanf("%s",st+1);int len=strlen(st+1);for (int i=1;i<=len;i++) insert(st[i]-'a',i);for (int i=1;i<=len;i++) rt[Lst[i]]=update(rt[Lst[i]],1,sz,i);Init();int Case=read();while (Case--){int l=read(),r=read();scanf("%s",St+1);int Len=strlen(St+1),id=Len+1;nw[0]=1;for (int i=1;i<=Len;i++){if (t[nw[i-1]][St[i]-'a']&&query(rt[t[nw[i-1]][St[i]-'a']],1,sz,l+i-1,r)) nw[i]=t[nw[i-1]][St[i]-'a'];else { id=i; break; }}int flag=0;for (int i=id;i>=1;i--){for (int j=(i>Len?0:St[i]-'a'+1);j<26;j++)if (t[nw[i-1]][j]&&query(rt[t[nw[i-1]][j]],1,sz,l+i-1,r)) { print(i-1,j),flag=1; break; } if (flag) break;}if (!flag) puts("-1");}return 0; }Code 2
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> #include <cassert> #include <string.h> //#include <unordered_set> //#include <unordered_map> //#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B) #define PB(A) push_back(A) #define SIZE(A) ((int)A.size()) #define LEN(A) ((int)A.length()) #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define fi first #define se second using namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; } template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll; typedef unsigned long long ull; typedef long double lod; typedef pair<int,int> PR; typedef vector<int> VI;const lod eps=1e-11; const lod pi=acos(-1); const int oo=1<<30; const ll loo=1ll<<62; const int mods=1e9+7; const int MAXN=400005; const int INF=0x3f3f3f3f;//1061109567 /*--------------------------------------------------------------------*/ inline int read() {int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f; } char St[MAXN],st[MAXN]; int ls[MAXN*20],rs[MAXN*20],s[MAXN*20],rt[MAXN],nw[MAXN],Q[MAXN],nodenum=0; void print(int x,int y) {for (int i=1;i<=x;i++) putchar(St[i]);int t=0;while (!(y&1)) y>>=1,t++;putchar(t+'a');puts(""); }int query(int x,int l,int r,int L,int R) {if (L>R||!x) return 0;if (l>=L&&r<=R) return s[x];int mid=(l+r)>>1;if (R<=mid) return query(ls[x],l,mid,L,R);else if (L>mid) return query(rs[x],mid+1,r,L,R);else return query(ls[x],l,mid,L,mid)|query(rs[x],mid+1,r,mid+1,R); } int merge(int x,int y) {if (!x||!y) return x|y;int z=++nodenum;s[z]=s[x]|s[y];ls[z]=merge(ls[x],ls[y]);rs[z]=merge(rs[x],rs[y]);return z; } int update(int x,int l,int r,int y,int z) {if (!x) x=++nodenum;s[x]|=z;if (l==r) return x;int mid=(l+r)>>1;if (y<=mid) ls[x]=update(ls[x],l,mid,y,z);else rs[x]=update(rs[x],mid+1,r,y,z); return x; }int t[MAXN][26],len[MAXN],fa[MAXN],Lst[MAXN],sz=2,lst=1; void insert(int c,int id) {int p=lst,np=lst=sz++;len[np]=len[p]+1,Lst[id]=np;for (;p&&!t[p][c];p=fa[p]) t[p][c]=np;if (!p) { fa[np]=1; return; }int q=t[p][c];if (len[q]==len[p]+1) fa[np]=q;else{int nq=sz++;fa[nq]=fa[q];fa[np]=fa[q]=nq;len[nq]=len[p]+1;memcpy(t[nq],t[q],sizeof t[0]);for (;t[p][c]==q;p=fa[p]) t[p][c]=nq;} } int c[MAXN]={1},a[MAXN]; void Init() {for (int i=1;i<sz;i++) c[i]=0;for (int i=1;i<sz;i++) c[len[i]]++;for (int i=1;i<sz;i++) c[i]+=c[i-1];for (int i=sz-1;i>=1;i--) a[--c[len[i]]]=i;for (int i=sz-1;i>=1;i--) rt[fa[a[i]]]=merge(rt[fa[a[i]]],rt[a[i]]); } signed main() {scanf("%s",st+1);int len=strlen(st+1); Lst[0]=1;for (int i=1;i<=len;i++) insert(st[i]-'a',i);for (int i=1;i<=len;i++) rt[Lst[i-1]]=update(rt[Lst[i-1]],0,sz,i-1,1<<(st[i]-'a'));Init();int Case=read();while (Case--){int l=read(),r=read();scanf("%s",St+1);int Len=strlen(St+1),id=Len;nw[0]=1;for (int i=1;i<=Len;i++){if (((Q[i-1]=query(rt[nw[i-1]],0,sz,l+i-2,r-1))>>(St[i]-'a'))&1) nw[i]=t[nw[i-1]][St[i]-'a'];else { id=i-1; break; }}Q[Len]=query(rt[nw[Len]],0,sz,l+Len-1,r-1);int flag=0;for (int i=id;i>=0;i--){int p=Q[i],q=(i>=Len?0:St[i+1]-'a'+1);if (p>=(1<<q)) { p^=p&((1<<q)-1),print(i,p&(-p)),flag=1; break; }}if (!flag) puts("-1");}return 0; }總結(jié)
以上是生活随笔為你收集整理的CF1037H. Security的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 光遇圣岛季兑换物品详细介绍 分别需要多少
- 下一篇: 2020年国庆节中秋节放假安排 2020