日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

F. Paper Grading(Trie树+dfs序+二维数点)

發(fā)布時間:2023/12/3 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 F. Paper Grading(Trie树+dfs序+二维数点) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

F. Paper Grading

大佬題解
一般關(guān)于前綴的問題基本都是Trie樹。

首先將所給字符串建立一棵Trie樹,Trie能夠解決一個字符串在一個字符串集合中出現(xiàn)的次數(shù),而查詢前綴次數(shù)只需要找到Trie樹中所給字符末尾的位置,那么其子樹中打標(biāo)記的次數(shù)即前綴次數(shù)。

由于子樹dfs序[L,R]連續(xù),于是把字典樹按照dfs序標(biāo)記,即變成區(qū)間查詢問題[l,r]中[L,R]之間數(shù)的個數(shù),二位偏序問題。

樹套樹(樹狀數(shù)組套下標(biāo)線段樹)即可解決,要動態(tài)開點(diǎn)!

#include<iostream> using namespace std; const int N=200010; char s[N]; int n,q,pos[N]; // Trie樹 struct T1 {int tree[N][26],idx;int insert(char s[]){int p=0;for(int i=0;s[i];i++){int t=s[i]-'a';if(!tree[p][t]) tree[p][t]=++idx;p=tree[p][t];}return p;}int find(char s[],int k){int p=0;for(int i=0;i<k;i++){int t=s[i]-'a';if(!tree[p][t]) return -1;p=tree[p][t];}return p;} }Trie; // 動態(tài)開點(diǎn)線段樹 struct T2 {struct node{int l,r;int sz;}tree[N*40];int root[N],cnt;void update(int &u,int l,int r,int pos,int x){if(!u) u=++cnt;tree[u].sz+=x;if(l==r) return;int mid=l+r>>1;if(pos<=mid) update(tree[u].l,l,mid,pos,x);else update(tree[u].r,mid+1,r,pos,x);}int query(int u,int l,int r,int L,int R){if(!u) return 0;if(L<=l&&r<=R) return tree[u].sz;int mid=l+r>>1;int v=0;if(L<=mid) v+=query(tree[u].l,l,mid,L,R);if(R>mid) v+=query(tree[u].r,mid+1,r,L,R);return v;} }Segment; // dfs序轉(zhuǎn)化為區(qū)間 int dfn[N],sz[N],timestamp; void dfs(int u) {dfn[u]=++timestamp;sz[u]=1;for(int i=0;i<26;i++)if(Trie.tree[u][i]) dfs(Trie.tree[u][i]),sz[u]+=sz[Trie.tree[u][i]]; } // 樹狀數(shù)組 int lowbit(int x) {return x&-x;} void add(int k,int pos,int x) {for(;k<=n;k+=lowbit(k))Segment.update(Segment.root[k],1,timestamp,pos,x); } int sum(int k,int L,int R) {int res=0;for(;k;k-=lowbit(k))res+=Segment.query(Segment.root[k],1,timestamp,L,R);return res; } int main() {cin>>n>>q;for(int i=1;i<=n;i++){cin>>s;pos[i]=Trie.insert(s);}dfs(0);for(int i=1;i<=n;i++)add(i,dfn[pos[i]],1);while(q--){int op;cin>>op;if(op==1){int u,v;cin>>u>>v;add(u,dfn[pos[u]],-1);add(v,dfn[pos[v]],-1);add(u,dfn[pos[v]],1);add(v,dfn[pos[u]],1);swap(pos[u],pos[v]);}else{int k,l,r;cin>>s;cin>>k>>l>>r;int u=Trie.find(s,k);if(u==-1) cout<<0<<'\n';else{int L=dfn[u],R=dfn[u]+sz[u]-1;cout<<sum(r,L,R)-sum(l-1,L,R)<<'\n';}}}return 0; }

cdq分治,帶修改二維數(shù)點(diǎn),把時間軸當(dāng)作一維即靜態(tài)三維數(shù)點(diǎn),cdq分治+樹狀數(shù)組

#include<iostream> #include<algorithm> using namespace std; const int N=200010; char s[N]; int n,m,pos[N]; // Trie樹 struct T1 {int tree[N][26],idx;int insert(char s[]){int p=0;for(int i=0;s[i];i++){int t=s[i]-'a';if(!tree[p][t]) tree[p][t]=++idx;p=tree[p][t];}return p;}int find(char s[],int k){int p=0;for(int i=0;i<k;i++){int t=s[i]-'a';if(!tree[p][t]) return -1;p=tree[p][t];}return p;} }Trie; // dfs序轉(zhuǎn)化為區(qū)間 int dfn[N],sz[N],timestamp; void dfs(int u) {dfn[u]=++timestamp;sz[u]=1;for(int i=0;i<26;i++)if(Trie.tree[u][i]) dfs(Trie.tree[u][i]),sz[u]+=sz[Trie.tree[u][i]]; } int ans[N]; struct node {int op;int a,b,c,cnt;int sign,id; }q[N*5]; int st[N]; bool cmpb(const node &x,const node &y) {return x.b<y.b||x.b==y.b&&x.op<y.op; } int fw[N]; int lowbit(int x){return x&-x;} void update(int k,int x){for(;k<=timestamp;k+=lowbit(k)) fw[k]+=x;} int query(int k){int res=0;for(;k;k-=lowbit(k)) res+=fw[k];return res;} void solve(int l,int r) {if(l>=r) return;int mid=l+r>>1;solve(l,mid),solve(mid+1,r);int i=l;for(int j=mid+1;j<=r;j++){if(q[j].op==1) continue;while(i<=mid&&q[i].b<=q[j].b){if(q[i].op==1) update(q[i].c,q[i].cnt);i++;}ans[q[j].id]+=q[j].sign*query(q[j].c);}while(i>l){i--;if(q[i].op==1) update(q[i].c,-q[i].cnt);}inplace_merge(q+l,q+mid+1,q+r+1,cmpb); } int main() {cin>>n>>m;for(int i=1;i<=n;i++){cin>>s;pos[i]=Trie.insert(s);}dfs(0);int cnt=0;for(int i=1;i<=n;i++)q[++cnt]={1,0,i,dfn[pos[i]],1};for(int i=1;i<=m;i++){int op;cin>>op;if(op==1){int u,v;cin>>u>>v;q[++cnt]={1,i,u,dfn[pos[u]],-1};q[++cnt]={1,i,v,dfn[pos[v]],-1};q[++cnt]={1,i,u,dfn[pos[v]],+1};q[++cnt]={1,i,v,dfn[pos[u]],+1};swap(pos[u],pos[v]);}else{st[i]=1;int k,l,r;cin>>s;cin>>k>>l>>r;int u=Trie.find(s,k);if(u==-1) ans[i]=0;else{int L=dfn[u],R=dfn[u]+sz[u]-1;q[++cnt]={2,i,r,R,0,1,i};q[++cnt]={2,i,l-1,R,0,-1,i};q[++cnt]={2,i,r,L-1,0,-1,i};q[++cnt]={2,i,l-1,L-1,0,1,i};}}}solve(1,cnt);for(int i=1;i<=m;i++)if(st[i]) cout<<ans[i]<<'\n';return 0; }

寫代碼過程中總是弄不清記得東西,每次都是一層一層的想,尤其是dfs序問題,很迷糊,還是要多寫,多積累!!!要不然訓(xùn)練總是掛機(jī)

總結(jié)

以上是生活随笔為你收集整理的F. Paper Grading(Trie树+dfs序+二维数点)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 寡妇av| 日韩卡一卡二 | 美痴女~美人上司北岛玲 | 国产又大又黑又粗免费视频 | 红桃视频国产精品 | 91蜜桃婷婷狠狠久久综合9色 | 青青青国产在线 | 波多野结衣视频一区 | 日韩香蕉视频 | 少妇一级淫片免费放 | 一二区精品 | 狠狠操很很干 | 特级丰满少妇一级aaaa爱毛片 | 日韩在线www| 青苹果av| 一区二区视 | 亚洲视频在线观看网站 | 色小姐综合 | 亚洲精品一区二区三区在线观看 | 成人综合区一区 | 亚洲成人免费在线观看 | 三级黄网 | 国产福利免费看 | 欧美jizzhd欧美18 | 97久久久久久久 | 欧美日韩国产一区在线 | 日本一区二区三区免费在线观看 | 曰批又黄又爽免费视频 | 国产h视频 | 久久久久久久无码 | 久久不雅视频 | 天天操操夜夜操操 | 激情亚洲色图 | av毛片在线免费看 | 欧美在线黄色 | 五月天综合激情 | 久久伊人超碰 | 我爱av好色 | 精品国产av无码 | 精品一区久久 | 日韩极品在线 | 影音先锋黄色网址 | 免费在线中文字幕 | 欧美mv日韩mv国产网站 | 日韩电影福利 | av网站在线免费播放 | 国产激情无套内精对白视频 | 九九色视频 | 国产精品乱码一区二区三区 | 又色又爽又黄gif动态图 | 最新日韩在线 | 91视频精品 | a级在线观看视频 | 99久久久精品免费观看国产 | 精品国产高清在线观看 | av一级| 婷婷在线网 | 波多野结衣福利 | 亚洲精品成人 | 国产哺乳奶水91在线播放 | 免费观看一级一片 | 国产精品久久久一区 | 好男人在线观看 | 亚洲a级在线观看 | 老汉色av | 日韩精品免费看 | 肉色超薄丝袜脚交一区二区 | 小箩莉末发育娇小性色xxxx | 久久青草热 | 高潮一区二区 | 成人毛片100免费观看 | www.欧美成人 | 伊人久久久久久久久久 | 日本jizz在线观看 | 日本一级一片免费视频 | 国产高清成人久久 | 亚洲第一二三四区 | 日韩字幕在线 | 91精品国产一区二区三竹菊影视 | 一区二区三区免费视频观看 | 国产乱码77777777 | 91国偷自产中文字幕久久 | 日本亚洲精品 | youjizz欧美| 欧美性三级 | 国产精品夜夜夜爽张柏芝 | 国产破处av | 91精品国产综合久久久久 | 日韩欧美久久精品 | 手机看片1024日韩 | 玩偶姐姐在线观看免费 | 69午夜 | 在线欧美亚洲 | 丁香花电影免费播放在线观看 | 亚洲 欧美 成人 | 国产精品久久久久久无人区 | 中文字幕中出 | 亚欧在线免费观看 | 久久网伊人 |