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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2021“MINIEYE杯”中国大学生算法设计超级联赛(10)Pty loves string(Border+二维数点)

發(fā)布時間:2023/12/3 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021“MINIEYE杯”中国大学生算法设计超级联赛(10)Pty loves string(Border+二维数点) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Pty loves string

建立Border樹后,發(fā)現(xiàn)可以轉化成兩個子樹中相同點的數(shù)量,時間戳轉化為連續(xù)的區(qū)間后相當于有兩個數(shù)組,每次給兩個區(qū)間,問區(qū)間相同點權的數(shù)目。

第一個數(shù)組作為區(qū)間,第二個數(shù)組作為權值。將第一個數(shù)組建立主席樹,每次插入的是第一個區(qū)間位置的權值映射到第二個數(shù)組中的權值。然后就是區(qū)間查詢。

#include<bits/stdc++.h>using namespace std; const int N=200010; char s[N]; int n,m; int ne1[N],ne2[N]; vector<int> e1[N],e2[N]; int dfn1[N],dfn2[N],sz1[N],sz2[N],timestamp; int id[N]; struct node {int l,r,v; }tree[N*40]; int rt[N],cnt; void insert(int &u,int o,int l,int r,int v) {tree[u=++cnt]=tree[o];tree[u].v++;if(l==r) return;int mid=l+r>>1;if(v<=mid)insert(tree[u].l,tree[o].l,l,mid,v);elseinsert(tree[u].r,tree[o].r,mid+1,r,v); } int query(int u,int o,int l,int r,int L,int R) {if(L<=l&&r<=R) return tree[u].v-tree[o].v;int v=0;int mid=l+r>>1;if(L<=mid) v+=query(tree[u].l,tree[o].l,l,mid,L,R);if(R> mid) v+=query(tree[u].r,tree[o].r,mid+1,r,L,R);return v; } void dfs1(int u) {sz1[u]=1;dfn1[u]=++timestamp;id[timestamp]=u;for(int v:e1[u]){dfs1(v);sz1[u]+=sz1[v];} } void dfs2(int u) {sz2[u]=1;dfn2[u]=++timestamp;for(int v:e2[u]){dfs2(v);sz2[u]+=sz2[v];} } void init() {for(int i=1;i<=cnt;i++) tree[i]={0,0,0};cnt=0;for(int i=0;i<=n+1;i++) e1[i].clear(),e2[i].clear();ne1[1]=0;for(int i=2,j=0;i<=n;i++){while(j&&s[i]!=s[j+1]) j=ne1[j];if(s[i]==s[j+1]) j++;ne1[i]=j;}ne2[n]=n+1;for(int i=n-1,j=n+1;i;i--){while(j<=n&&s[i]!=s[j-1]) j=ne2[j];if(s[i]==s[j-1]) j--;ne2[i]=j;} } void build() {for(int i=1;i<=n;i++) e1[ne1[i]].push_back(i),e2[ne2[i]].push_back(i);timestamp=0;dfs1(0);timestamp=0;dfs2(n+1);for(int i=1;i<=n+1;i++) insert(rt[i],rt[i-1],1,n+1,dfn2[id[i]+1]); } int main() {int Tc;scanf("%d",&Tc);while(Tc--){scanf("%d%d%s",&n,&m,s+1);init();build();while(m--){int x,y;scanf("%d%d",&x,&y);if(x+y>n) {puts("0");continue;}y=n-y+1;printf("%d\n",query(rt[dfn1[x]+sz1[x]-1],rt[dfn1[x]-1],1,n+1,dfn2[y],dfn2[y]+sz2[y]-1));}}return 0; }

總結

以上是生活随笔為你收集整理的2021“MINIEYE杯”中国大学生算法设计超级联赛(10)Pty loves string(Border+二维数点)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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