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

F. Paper Grading

大佬题解
一般关于前缀的问题基本都是Trie树。

首先将所给字符串建立一棵Trie树,Trie能够解决一个字符串在一个字符串集合中出现的次数,而查询前缀次数只需要找到Trie树中所给字符末尾的位置,那么其子树中打标记的次数即前缀次数。

由于子树dfs序[L,R]连续,于是把字典树按照dfs序标记,即变成区间查询问题[l,r]中[L,R]之间数的个数,二位偏序问题。

树套树(树状数组套下标线段树)即可解决,要动态开点!

#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;
// 动态开点线段树
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序转化为区间
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 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分治,带修改二维数点,把时间轴当作一维即静态三维数点,cdq分治+树状数组

#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序转化为区间
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序问题,很迷糊,还是要多写,多积累!!!要不然训练总是挂机

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AT2164-[AGC006C]Rabbit Exercise【差分,倍增,数学期望】

正题 题目链接:https://www.luogu.com.cn/problem/AT2164 题目大意 nnn只兔子编号为1∼n1\sim n1∼n&#xff0c;第iii只在坐标轴xix_ixi​处。然后mmm次跳跃&#xff0c;每次给出aia_iai​&#xff0c;编号为aia_iai​的兔子会等概率的选取ai−1a_{i-1}ai−1​和ai1a_{i1}ai1…

k-substrings(CF961F)

正题 luogu CF961F 题目大意 给你一个字符串T&#xff0c;对于k1~n/2&#xff0c;找到最长的串s&#xff0c;满足s是T左右各删除k个字符构成的字串t的前缀后缀&#xff08;不能是整个字符串&#xff09; 解题思路 不难发现&#xff0c;k的答案左右各删一个字符必定能得到k1的…

全面支持开源,微软加速 Visual Studio 和 Azure DevOps 云升级

在 2018 微软技术暨生态大会&#xff08;Microsoft Tech Summit&#xff09;上&#xff0c;微软宣布围绕 Visual Studio 和 Visual Studio Code 开发平台提供一系列新功能与服务&#xff0c;并对 Azure DevOps 研发云进行整合升级&#xff0c;通过 Visual Studio 开发平台与微软…

求约数个数的和

今天一下午都在研究约数的各种性质。。。 求约数个数的和可以用线性筛的方式&#xff0c;线性求解的方式&#xff0c;这应该是最快的 [数论]线性筛——约数个数与约数和 除此之外还有代码更简便方法&#xff1a; 对应的例题 方法一&#xff1a; #include <iostream> …

I. Space Station(hash记忆化+dp)

《文章》陆游 文章本天成&#xff0c;妙手偶得之。 粹然无疵瑕&#xff0c;岂复须人为。 君看古彝器&#xff0c;巧拙两无施。 汉最近先秦&#xff0c;固已殊淳漓。 胡部何为者&#xff0c;豪竹杂哀丝。 后夔不复作&#xff0c;千载谁与期&#xff1f; I. Space Station 大佬…

HttpClient参观记:.net core 2.2 对HttpClient到底做了什么?

.net core 于 10月17日发布了 ASP.NET Core 2.2.0 -preview3&#xff0c;在这个版本中&#xff0c;我看到了一个很让我惊喜的新特性&#xff1a;HTTP Client Performance Improvements &#xff0c;而且在Linux上性能提升了60% !之前就一直苦于 HttpClient 的糟糕特性&#xff…

【线段树】Serious Business(CF1648D)

正题 luogu CF1648D 题目大意 有一个 3*n 的矩阵&#xff0c;1,3行没有行走限制&#xff0c;对于第2行&#xff0c;有m个区间&#xff0c;覆盖第 i 个区间有 kik_iki​ 的代价&#xff0c;只有覆盖的位置才能走&#xff0c;让你从 (1,1) 走到 (3,n)&#xff08;只能向下和向右…

P6378-[PA2010]Riddle【2-SAT】

正题 题目链接:https://www.luogu.com.cn/problem/P6378 题目大意 给出nnn个点mmm条边的一张无向图&#xff0c;图中有kkk种颜色的点。 要求每种颜色选择一个点作为关键点&#xff0c;满足每条边两边至少有一个关键点 求是否有满足的方案 1≤n,m,k≤1061\leq n,m,k\leq 10^…

后缀数组(讲解)

子串&#xff1a;从原串中选取连续的一段&#xff0c;即子串 空串也是子串 后缀&#xff1a;suf(k)为s(k…n)构成的子串 任何子串都是某个后缀的前缀 最长公共前缀 lcp(suf(i),suf(j)) 问题&#xff1a; 将所有后缀suf(1),suf(2),suf(N)按照字典序从小到大排序 暴力sort N2 …

codeforces1471 D. Strange Definition

D. Strange Definition 大佬题解 由lcm(x,y)xygcd(x,y)lcm(x,y)\frac{xy}{gcd(x,y)}lcm(x,y)gcd(x,y)xy​可知&#xff0c;如果lcm(x,y)gcd(x,y)xygcd2(x,y)\frac{lcm(x,y)}{gcd(x,y)}\frac{xy}{gcd^2(x,y)}gcd(x,y)lcm(x,y)​gcd2(x,y)xy​是完全平方数&#xff0c;那么xyxy…

2018 上海.NET职位围观报告

我一直说我是夏眠动物&#xff0c;如今已经11月份了&#xff0c;差不多也该活过来了&#xff0c;所以我决定写篇文章给各位.NET的支持者们和公司打打气&#xff0c;也算是为社区做点贡献吧。我最近主要干了两件事&#xff1a;让NPOI支持.NET Core&#xff0c;现已发布2.4版本。…

P5437-[XR-2]约定【拉格朗日差值,数学期望】

正题 题目链接:https://www.luogu.com.cn/problem/P5437 题目大意 nnn个点的完全图&#xff0c;连接i,ji,ji,j的边权值为(ij)k(ij)^k(ij)k。随机选出一个生成树&#xff0c;求期望边权和。 1≤n<998244353,1≤k≤1071\leq n<998244353,1\leq k\leq 10^71≤n<99824435…

【模板】分散层叠算法(P6466)

正题 P6466 题目大意 给你 k 个大小为 n 的数组&#xff0c;有q次询问&#xff0c;每次询问回答x在k个数组中的后继的异或和 解题思路 分散层叠模板 code #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll …

后缀数组(后续)

文章目录**后缀数组 Height**两个子串最长公共前缀**求Height数组**比较一个字符串的两个子串的大小关系不同子串的数目出现至少k次的子串的最大长度**总结&#xff1a;**代码&#xff1a;后缀数组 Height 利用后缀数组快速求出2个后缀的lcp长度 lcp:最长公共前缀 lcp(suf(i),…

codeforces1472 G. Moving to the Capital

G. Moving to the Capital 先bfs一边&#xff0c;求出距1号点的最短路用数组d1[]记录&#xff0c;求的过程中如果当前点t遍历到之前遍历过的点j意味着这条边就是能够拉近与1号点距离的边&#xff08;横向边或者后向边&#xff09;那么就用d1[j]更新d2[t]&#xff0c;d2[]表示最…

P3793-由乃救爷爷【分块,ST表】

正题 题目链接:https://www.luogu.com.cn/problem/P3793 题目大意 给出nnn个数字的一个序列mmm次询问区间最大值 保证数据随机 1≤n,m≤21071\leq n,m\leq 2\times 10^71≤n,m≤2107 解题思路 使用STSTST表可以做到O(1)O(1)O(1)询问&#xff0c;但是预处理的时空复杂度都是…

【DP】Mod Mod Mod(CF889E)

正题 CF889E luogu 题目大意 给你 n 个数&#xff0c;让你选择一个X&#xff0c;使得 ∑i1nXmoda1moda2...modai\sum_{i1}^nX\mod a_1\mod a_2...\mod a_i∑i1n​Xmoda1​moda2​...modai​ 最大 解题思路 可以发现必定存在一个 i &#xff0c;使得当前点贡献为 aia_iai​&a…

老张 .NetCore与Vue 框架学习

缘起作为一个.Net攻城狮已经4年有余了&#xff0c;一直不温不火&#xff0c;正好近来项目不是很忙&#xff0c;闲得无聊&#xff0c;搞一搞新技术&#xff0c;一方面是打发无聊的时间&#xff0c;一方面也是督促自己该学习辣&#xff01;身边的大神都转行的转行&#xff0c;加薪…

【平衡规划】Arithmetic Operations(CF1654E)

正题 CF1654E luogu 正题 给你一个正整数序列&#xff0c;你可以让一个位置变成任意整数&#xff0c;问你最少修改多少个数&#xff0c;能使得其成为等差序列 解题思路 考虑根号分治 对于公差小于 n\sqrt{n}n​ 的&#xff0c;直接枚举公差&#xff0c;然后枚举所有点&…

P1251-餐巾计划问题【费用流】

正题 题目链接:https://www.luogu.com.cn/problem/P1251 题目大意 NNN天&#xff0c;第iii天需要aia_iai​个餐巾。 每个餐巾价格为ppp&#xff0c;使用完后有两种清洗方法 清洗mmm天&#xff0c;费用为fff清洗nnn天&#xff0c;费用为sss 求满足所有需求的最小花费 1≤N≤…