BZOJ1014: [JSOI2008]火星人prefix

BZOJ1014: [JSOI2008]火星人prefix

Description

  火星人最近研究了一種操作:求一個字串兩個后綴的公共前綴。

比方說,有這樣一個字符串:madamimadam,我們將這個字符串的各個字符予以標號:

序號: 1 2 3 4 5 6 7 8 9 10 11

字符: m a d a m i m a d? a? m

現在,火星人定義了一個函數LCQ(x, y),表示:該字符串中第x個字符開始的字串,與該字符串中第y個字符開始的字串,兩個字串的公共前綴的長度。

比方說,LCQ(1, 7) = 5, LCQ(2, 10) = 1, LCQ(4, 7) = 0

在研究LCQ函數的過程中,火星人發現了這樣的一個關聯:

如果把該字符串的所有后綴排好序,就可以很快地求出LCQ函數的值;同樣,如果求出了LCQ函數的值,也可以很快地將該字符串的后綴排好序。

盡管火星人聰明地找到了求取LCQ函數的快速算法,但不甘心認輸的地球人又給火星人出了個難題:

在求取LCQ函數的同時,還可以改變字符串本身。

具體地說,可以更改字符串中某一個字符的值,也可以在字符串中的某一個位置插入一個字符。

地球人想考驗一下,在如此復雜的問題中,火星人是否還能夠做到很快地求取LCQ函數的值。

Input

第一行給出初始的字符串。

第二行是一個非負整數M,表示操作的個數。

接下來的M行,每行描述一個操作。

操作有3種,如下所示:
1、詢問。語法:Q x y,x,y均為正整數。功能:計算LCQ(x,y)限制:1<=x,y<=當前字符串長度。
2、修改。語法:R x d,x是正整數,d是字符。功能:將字符串中第x個數修改為字符d。限制:x不超過當前字符串長度。
3、插入:語法:I x d,x是非負整數,d是字符。功能:在字符串第x個字符之后插入字符d,如果x=0,則在字符串開頭插入。限制:x不超過當前字符串長度

Output

對于輸入文件中每一個詢問操作,你都應該輸出對應的答案。一個答案一行。

Sample Input

madamimadam
7
Q 1 7
Q 4 8
Q 10 11
R 3 a
Q 1 7
I 10 a
Q 2 11

Sample Output

5
1
0
2
1

HINT

1、所有字符串自始至終都只有小寫字母構成。

2、M<=150,000

3、字符串長度L自始至終都滿足L<=100,000

4、詢問操作的個數不超過10,000個。

對于第1,2個數據,字符串長度自始至終都不超過1,000

對于第3,4,5個數據,沒有插入操作。

題解Here!

這個題,難到掉牙了。。。

看到字符串處理,坑能會想到?AC自動機/?SA?/?SAM 等等。

但是看到有插入與修改操作,?Splay?啊!

然后維護一個?hash?值:

a[rt].hash=a[lson].hash*val[a[rson].s+1]+val[a[rson].s]*(a[rt].v-'a'+1)+a[rson].hash;
//lson是rt的左孩子,rson是rt的右孩子
//a[rt].v表示rt節點存的字母
//a[rt].s表示rt節點的子樹大小
//val[i]表示第i位的hash值,即27^i

剩下的就是?Splay?基本操作,具體可見BZOJ1500: [NOI2005]維修數列

附代碼:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define MAXN 100010
using namespace std;
int n,m;
int root=0,size=1;
char ch[MAXN];
unsigned val[MAXN];
struct Splay{int f,s,son[2];char v;unsigned hash;
}a[MAXN];
inline int read(){int date=0,w=1;char c=0;while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}return date*w;
}
inline void pushup(int rt){if(!rt)return;int lson=a[rt].son[0],rson=a[rt].son[1];a[rt].s=a[lson].s+a[rson].s+1;a[rt].hash=a[lson].hash*val[a[rson].s+1]+val[a[rson].s]*(a[rt].v-'a'+1)+a[rson].hash;
}
inline void turn(int rt,int k){int x=a[rt].f,y=a[x].f;a[x].son[k^1]=a[rt].son[k];if(a[rt].son[k])a[a[rt].son[k]].f=x;a[rt].f=y;if(y)a[y].son[a[y].son[1]==x]=rt;a[x].f=rt;a[rt].son[k]=x;pushup(x);pushup(rt);
}
void splay(int rt,int ancestry){while(a[rt].f!=ancestry){int x=a[rt].f,y=a[x].f;if(y==ancestry)turn(rt,a[x].son[0]==rt);else{int k=a[y].son[0]==x?1:0;if(a[x].son[k]==rt){turn(rt,k^1);turn(rt,k);}else{turn(x,k);turn(rt,k);}}}if(ancestry==0)root=rt;
}
inline int newnode(char x){int rt=size++;a[rt].v=x;a[rt].hash=x-'a'+1;a[rt].s=1;a[rt].son[0]=a[rt].son[1]=0;return rt;
}
int buildtree(int l,int r){if(l>r)return 0;int mid=l+r>>1,lson=0,rson=0;lson=buildtree(l,mid-1);int rt=newnode(ch[mid]);rson=buildtree(mid+1,r);a[rt].son[0]=lson;a[rt].son[1]=rson;if(lson)a[lson].f=rt;if(rson)a[rson].f=rt;pushup(rt);return rt;
}
int kth(int rt,int k){while(1){int y=a[rt].son[0];if(k>a[y].s+1){k-=a[y].s+1;rt=a[rt].son[1];}else if(k<=a[y].s)rt=y;else return rt;}
}
inline int split(int l,int r){int front=kth(root,l),next=kth(root,r);splay(front,0);splay(next,front);return a[next].son[0];
}
inline void change(int x,char y){int front=kth(root,x),next=kth(root,x+2);splay(front,0);splay(next,front);int u=a[next].son[0];a[u].v=y;a[u].hash=y-'a'+1;pushup(next);pushup(front);
}
inline void insert(int x,char y){int front=kth(root,x),next=kth(root,x+1);splay(front,0);splay(next,front);int rt=newnode(y);a[next].son[0]=rt;a[rt].f=next;pushup(next);pushup(front);
}
inline bool check(int x,int y,int len){int u=split(x,x+len+1),hu=a[u].hash;int v=split(y,y+len+1),hv=a[v].hash;return (hu==hv);
}
void work(){char f[2],y[2];int x,k;while(m--){scanf("%s",f);x=read();if(f[0]=='Q'){k=read();int l=1,r=min(size-x,size-k)-2,mid;while(l<=r){mid=l+r>>1;if(check(x,k,mid))l=mid+1;else r=mid-1;}printf("%d\n",r);}if(f[0]=='R'){scanf("%s",y);change(x,y[0]);}if(f[0]=='I'){scanf("%s",y);insert(x+1,y[0]);}}
}
void init(){scanf("%s",ch+1);n=strlen(ch+1);val[0]=1;for(int i=1;i<=MAXN-5;i++)val[i]=val[i-1]*27;root=buildtree(0,n+1);m=read();
}
int main(){init();work();return 0;
}

?

轉載于:https://www.cnblogs.com/Yangrui-Blog/p/9343817.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/389046.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/389046.shtml
英文地址,請注明出處:http://en.pswp.cn/news/389046.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

redis將散裂中某個值自增_這些Redis命令你都掌握了沒?

本章主要內容字符串命令、列表命令和集合命令散列命令和有序集合命令發布命令與訂閱命令其他命令本章將介紹一些沒有在第1章和第2章出現過的Redis命令&#xff0c;學習這些命令有助于讀者在已有示例的基礎上構建更為復雜的程序&#xff0c;并學會如何更好地去解決自己遇到的問題…

asp.net的MessageBox

public class MessageBox{ public enum MsgButton { /// <summary> /// 只是OK按鈕 /// </summary> OK 1, /// <summary> /// 提示是否確定 /// </summary> OKCancel 2 } publ…

深入理解激活函數

為什么需要非線性激活函數&#xff1f; 說起神經網絡肯定會降到神經函數&#xff0c;看了很多資料&#xff0c;也許你對激活函數這個名詞會感覺很困惑&#xff0c; 它為什么叫激活函數&#xff1f;它有什么作用呢&#xff1f; 看了很多書籍上的講解說會讓神經網絡變成很豐富的…

如何一鍵部署項目、代碼自動更新

為什么80%的碼農都做不了架構師&#xff1f;>>> 摘要&#xff1a;my-deploy:由nodejs寫的一個自動更新工具,理論支持所有語言(php、java、c#)的項目,支持所有git倉庫(bitbucket、github等)。github效果如何?如果你的后端項目放在github、bitbucket等git倉庫中管理…

Kettle7.1在window啟動報錯

實驗環境&#xff1a; window10 x64 kettle7.1 pdi-ce-7.1.0.0-12.zip 錯誤現象&#xff1a; a java exception has occurred 問題解決&#xff1a; 運行調試工具 data-integration\SpoonDebug.bat //調試錯誤的&#xff0c;根據錯誤明確知道為何啟動不了&#xff0c;Y--Y-…

opa847方波放大電路_電子管放大電路當中陰極電阻的作用和選擇

膽機制作知識視頻&#xff1a;6P14單端膽機用示波器方波測試輸出波形詳細步驟演示完整版自制膽機試聽視頻&#xff1a;膽機播放《猛士的士高》經典舞曲 熟悉的旋律震撼的效果首先看下面這一張300B電子管電路圖&#xff1a;300B單端膽機原理圖圖紙里面畫圓圈的電阻就是放大電路當…

鍵盤鉤子

C#鍵盤鉤子//*************************鍵盤鉤子********************** //定義變量 public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); static int hKeyboardHook 0; HookProc KeyboardHookProcedure; /************************* * 聲明API函數 * ***…

matplotlib基礎函數函數 plot, figure

matplotlib.pyplot.plot(*args, scalexTrue, scaleyTrue,dataNone,**kwargs) 用線段和標記去繪制x和y。調用簽名&#xff1a; plot([x], y, [fmt], *, dataNone, **kwargs) plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)點或線的坐標由x, y給出 操作參數 fmt 是為了…

清潔數據ploy n_清潔屋數據

清潔數據ploy nAs a bootcamp project, I was asked to analyze data about the sale prices of houses in King County, Washington, in 2014 and 2015. The dataset is well known to students of data science because it lends itself to linear regression modeling. You …

redis安裝redis集群

NoSql數據庫之Redis1、什么是nosql&#xff0c;nosql的應用場景2、Nonsql數據庫的類型a) Key-valueb) 文檔型&#xff08;類似于json&#xff09;c) 列式存儲d) 圖式3、redis的相關概念kv型的。4、Redis的安裝及部署5、Redis的使用方法及數據類型a) Redis啟動及關閉b) Redis的數…

聯想拯救者y7000p加內存條_內存、硬盤不夠用?手把手教你升級聯想拯救者Y7000P...

由于這兩年內存價格的高企&#xff0c;主流筆記本的內存容量被鎖定在 8GB 已經有了相當長的時間。作為近幾個月最熱門的游戲本產品&#xff0c;聯想拯救者 Y7000P 除頂配之外同樣使用的是 8GB 內存和 512GB 固態硬盤的配置。所以買到這款機器的玩家多數都會選擇進行內存和硬盤的…

機器學習實踐一 logistic regression regularize

Logistic regression 數據內容&#xff1a; 兩個參數 x1 x2 y值 0 或 1 Potting def read_file(file):data pd.read_csv(file, names[exam1, exam2, admitted])data np.array(data)return datadef plot_data(X, y):plt.figure(figsize(6, 4), dpi150)X1 X[y 1, :]X2 X[…

ajax+webservice

版本為AJAX November CTP 三個示例分別為&#xff1a;1 帶參數的WS方法2 不帶參數的WS方法3 參數類型為DataTable的WS方法 一、WebMethod注意要點&#xff1a;1 WebMethod類需要添加命名空間 Microsoft.Web.Script.Services&#xff0c;此空間需要引用Microsoft.Web.Preview.dl…

深度學習數據擴張_適用于少量數據的深度學習結構

作者&#xff1a;Gorkem Polat編譯&#xff1a;ronghuaiyang導讀一些最常用的few shot learning的方案介紹及對比。傳統的CNNs (AlexNet, VGG, GoogLeNet, ResNet, DenseNet…)在數據集中每個類樣本數量較多的情況下表現良好。不幸的是&#xff0c;當你擁有一個小數據集時&…

時間管理

時間管理 時間管理是運用策略和技術&#xff0c;幫助你盡可能有效地利用你的時間。 不僅僅是要將時間用在正確的地方&#xff0c; 而且還要將盡可能有效地加以利用。 目前是如何利用時間的&#xff1a; 意識是時間管理的先決條件。目標提供路線圖。選擇是難點。 意識 第一條…

基于邊緣計算的實時績效_基于績效的營銷中的三大錯誤

基于邊緣計算的實時績效We’ve gone through 20% of the 21st century. It’s safe to say digitalization isn’t a new concept anymore. Things are fully or at least mostly online, and they tend to escalate in the digital direction. That’s why it’s important to…

本線程鉤子

鉤子其實就是調用一下API而已&#xff1a; 1、安裝鉤子&#xff1a;   SetWindowsHookEx 函數原形&#xff1a;HHOOK SetWindowsHookEx( int idHook, // 鉤子類型&#xff0c; HOOKPROC lpfn, // 鉤子函數地址…

Maven Web項目解決跨域問題

跨域問題目前筆者所用到的方案大致有三種:jsonp,SpringMVC 4以上注解方式和cros三方過濾器。 Jsonp JSONP(JSON with Padding)是一個非官方的協議&#xff0c;它允許在服務器端集成Script tags返回至客戶端&#xff0c;通過javascript callback的形式實現跨域訪問&#xff08;這…

為什么Facebook的API以一個循環作為開頭?

作者 | Antony Garand譯者 | 無明如果你有在瀏覽器中查看過發給大公司 API 的請求&#xff0c;你可能會注意到&#xff0c;JSON 前面會有一些奇怪的 JavaScript&#xff1a;為什么他們會用這幾個字節來讓 JSON 失效&#xff1f;為了保護你的數據 如果沒有這些字節&#xff0c;那…

城市軌道交通運營票務管理論文_城市軌道交通運營管理專業就業前景怎么樣?中職優選告訴你...

??城市軌道交通運營管理專業&#xff0c;專業就業前景怎么樣&#xff1f;就業方向有哪些&#xff1f;有很多同學都感覺很迷忙&#xff0c;為了讓更多的同學們了解城市軌道交通運營管理專業的就業前景與就業方向&#xff0c;整理出以下內容希望可以幫助同學們。城市軌道交通運…