jzoj3794,P1383-高级打字机【欧拉序,离线O(n)】
生活随笔
收集整理的這篇文章主要介紹了
jzoj3794,P1383-高级打字机【欧拉序,离线O(n)】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.org/problemnew/show/P1383
大意
三個操作
T c:加入一個字符c
U x:撤銷前x次操作(只包括T和U)
Q x:詢問當前第x個字符
解題思路
對于50%的數據U不會撤銷到U
所以我們可以直接暴力
#include<cstdio> #include<iostream> using namespace std; int n,x,w; char c,a[100001]; int main() {scanf("%d\n",&n);for (int i=1;i<=n;i++){cin>>c;if (c=='U'){scanf("%d",&x);w-=x;}else if (c=='Q'){scanf("%d",&x);printf("%c\n",a[x]);}else{cin>>c;a[++w]=c;}} }然后正題——撤銷撤銷
你知道嗎?它的撤銷可以撤銷撤銷!
它還可以撤銷撤銷撤銷
還可以撤銷撤銷撤銷撤銷
……
好了,這道題支持離線算法所以我們就用離線算法。
離線算法我們要先構一顆樹,我們發現如果是TT操作的話可以直接和下一個版本相連然后加一個字母,如果是U xU x操作的話那么版本xx就等于版本x?k?1x?k?1,所以我們連邊
然后用歐拉序來求所有的版本,時間負責度O(n)O(n)
代碼
#include<cstdio> #include<iostream> #include<vector> #define MN 100011 using namespace std; vector<int> q[MN+1];//vertor庫儲存詢問 struct node{int to,next,w; }a[MN+1]; int p,x,k,tot,ls[MN+1],n,ans[MN+1]; char c,st[MN+1],s[MN+1]; void addl(int x,int y)//連邊 {a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot; } void dfs(int x,int sto)//歐拉序求答案 {for(int i=ls[x];i;i=a[i].next)dfs(a[i].to,sto);//自己搜索連接的版本if (s[x]) st[sto]=s[x],dfs(x+1,sto+1);//直接接到下一個版本for (int i=0;i<q[x].size();i++)ans[q[x][i]]=st[ans[q[x][i]]];//計算答案 } int main() {scanf("%d\n",&n);for (int i=1;i<=n;i++){cin>>c;if (c=='T'){cin>>s[k++];//標記操作}else if (c=='Q'){scanf("%d",&x);q[k].push_back(++p);//記錄詢問ans[p]=x;}else if (c=='U'){k++;scanf("%d",&x);addl(k-x-1,k);//連邊}}dfs(0,1);//求答案for (int i=1;i<=p;i++)if (ans[i]) printf("%c\n",ans[i]);//原序輸出 }總結
以上是生活随笔為你收集整理的jzoj3794,P1383-高级打字机【欧拉序,离线O(n)】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯《宝可梦大集结》手游国服开启预约,安
- 下一篇: 联想推出拯救者掌机:搭载 AMD Z1