数据结构之trie树——First! G,电子字典,Type Printer,Nikitosh and xor

文章目录

  • [USACO12DEC]First! G
  • [JSOI2009]电子字典
  • [IOI2008] Type Printer
  • Nikitosh and xor

[USACO12DEC]First! G

luogu3065

考虑每一个字符串成为答案的可能

这意味着从字典树根到字符串最后一位就恰好对应重新定义的字典序

在第iii层的时候,想要走特定点,意味着这个点的字典序必须大于该层隶属于同一个父亲的所有点(兄弟)

建立u→vu\rightarrow vuv的有向边,表示uuu的字典序<v<v<v

最后肯定字典序不能出现环

拓扑判环

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define maxn 300005
queue < int > q;
int n, cnt, tot;
string s[maxn];
bool tag[maxn], vis[maxn], in[26];
int d[26];
bool E[26][26];
int trie[maxn][26];void insert( string s ) {int now = 0;int len = s.length();for( int i = 0;i < len;i ++ ) {int son = s[i] - 'a';if( ! trie[now][son] ) trie[now][son] = ++ cnt;now = trie[now][son];}tag[now] = 1;
}bool check( string s ) {memset( d, 0, sizeof( d ) );memset( E, 0, sizeof( E ) );memset( in, 0, sizeof( in ) );int len = s.length();int now = 0;for( int i = 0;i < len;i ++ ) {if( tag[now] ) return 0;int son = s[i] - 'a';for( int j = 0;j < 26;j ++ )if( son ^ j and ! E[son][j] and trie[now][j] ) {E[son][j] = 1;d[j] ++;}now = trie[now][son];}for( int i = 0;i < 26;i ++ )if( ! d[i] ) q.push( i );while( ! q.empty() ) {int now = q.front(); q.pop();in[now] = 1;for( int i = 0;i < 26;i ++ )if( E[now][i] ) {d[i] --;if( ! d[i] ) q.push( i );}}for( int i = 0;i < 26;i ++ )if( ! in[i] ) return 0;return 1;
}int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ ) {cin >> s[i];insert( s[i] );}int ans = 0;for( int i = 1;i <= n;i ++ )if( check( s[i] ) ) vis[i] = 1, ans ++;printf( "%d\n", ans );for( int i = 1;i <= n;i ++ )if( vis[i] ) cout << s[i] << endl;return 0;
}

[JSOI2009]电子字典

luogu4407

由于一个字符串长度不超过202020,且要求相异必须为111

其实状态数是可以直接爆搜的

#include <map>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxs 25
#define maxn 200005
map < int, int > mp;
int n, m, ans, cnt, len;
char s[maxn];
bool tag[maxn];
int trie[maxn][26];void insert() {int now = 0;len = strlen( s + 1 );for( int i = 1;i <= len;i ++ ) {int c = s[i] - 'a';if( ! trie[now][c] ) trie[now][c] = ++ cnt;now = trie[now][c];}tag[now] = 1;
}bool find() {int now = 0;len = strlen( s + 1 );for( int i = 1;i <= len;i ++ ) {int c = s[i] - 'a';if( ! trie[now][c] ) return 0;now = trie[now][c];}return tag[now];
}void dfs( int ip, int now, bool k ) {if( ip > len ) {if( k ) {ans += ( tag[now] and ! mp[now] );mp[now] = 1;}else for( int i = 0;i < 26;i ++ )if( ! mp[trie[now][i]] and tag[trie[now][i]] )ans ++, mp[trie[now][i]] = 1;return;}int c = s[ip] - 'a';if( k ) {if( ! trie[now][c] ) return;else dfs( ip + 1, trie[now][c], 1 );}else {if( trie[now][c] ) dfs( ip + 1, trie[now][c], 0 );dfs( ip + 1, now, 1 );for( int i = 0;i < 26;i ++ )if( trie[now][i] ) {dfs( ip, trie[now][i], 1 );dfs( ip + 1, trie[now][i], 1 );}}
}int main() {scanf( "%d %d", &n, &m );for( int i = 1;i <= n;i ++ ) {scanf( "%s", s + 1 );insert();}for( int i = 1;i <= m;i ++ ) {scanf( "%s", s + 1 );if( find() ) printf( "-1\n" );else {dfs( 1, 0, 0 );printf( "%d\n", ans );ans = 0;mp.clear();}}return 0;
}

[IOI2008] Type Printer

luogu4683

建立字典树

贪心的最后剩的字符越多越好

如果这个串不是最后一个,那么这个串肯定会原路返回直到遇到分叉点,走兄弟点

所以求出每个串与最近分叉点的距离,选最大值

然后把这个串一路上的点打上最后访问标记

接着开始遍历,先访问未标记点,再访问标记点,都清空打印机

最后把直到最后一个打印P为止的所有-操作都扔出操作顺序集合

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
#define maxn 500005
vector < char > ans;
vector < pair < int, int > > G;
int n, cnt;
char s[25];
bool tag[maxn], vis[maxn];
int dep[maxn], son[maxn];
int trie[maxn][26];void insert() {int len = strlen( s + 1 ), now = 0;for( int i = 1;i <= len;i ++ ) {int c = s[i] - 'a';if( ! trie[now][c] ) trie[now][c] = ++ cnt;dep[trie[now][c]] = dep[now] + 1;now = trie[now][c];}tag[now] = 1;
}void dfs1( int now, int lst ) {if( tag[now] ) G.push_back( make_pair( now, max( lst, 0 ) ) );int tot = 0;for( int i = 0;i < 26;i ++ )if( trie[now][i] ) tot ++;for( int i = 0;i < 26;i ++ )if( trie[now][i] )dfs1( trie[now][i], lst == -1 ? ( tot > 1 ? now : lst ) : lst );
}void dfs2( int now, int End, bool &flag ) {if( now == End ) { flag = 1; return; }for( int i = 0;i < 26;i ++ )if( trie[now][i] ) {vis[trie[now][i]] = 1;dfs2( trie[now][i], End, flag );if( flag ) return;vis[trie[now][i]] = 0;}
}void dfs3( int now ) {if( tag[now] ) ans.push_back( 'P' );for( int i = 0;i < 26;i ++ ) {if( trie[now][i] and ! vis[trie[now][i]] ) {ans.push_back( i + 'a' );dfs3( trie[now][i] );ans.push_back( '-' );}}for( int i = 0;i < 26;i ++ )if( vis[trie[now][i]] ) {ans.push_back( i + 'a' );dfs3( trie[now][i] );ans.push_back( '-' );}
}int main() {memset( son, -1, sizeof( son ) );scanf( "%d", &n );for( int i = 1;i <= n;i ++ ) {scanf( "%s", s + 1 );insert();}dfs1( 0, -1 );int Dep = 0, pos;for( int i = 0;i < G.size();i ++ ) {if( dep[G[i].first] - dep[G[i].second] > Dep ) {Dep = dep[G[i].first] - dep[G[i].second];pos = G[i].first;}}bool flag = 0;dfs2( 0, pos, flag );dfs3( 0 );for( int i = ans.size() - 1;~ i;i -- )if( ans[i] != 'P' ) continue;else { cnt = i + 1; break; }printf( "%d\n", cnt );for( int i = 0;i < cnt;i ++ )printf( "%c\n", ans[i] );return 0;
}

Nikitosh and xor

CodeChef

⨁i=lrai→br⨁bl−1\bigoplus_{i=l}^r a_i\rightarrow b_r\bigoplus b_{l-1}i=lraibrbl1

枚举iii,利用字典树,边插入边询问,将bib_ibi的二进制位从高到低放入字典树

求出bib_ibi与前面某个bjb_jbj的异或最大值

同理,从后往前操作一样

⨁i=lrai→cl⨁cr+1\bigoplus_{i=l}^r a_i\rightarrow c_l\bigoplus c_{r+1}i=lraiclcr+1

枚举iii,利用字典树,边插入边询问,将bib_ibi的二进制位从高到低放入字典树

求出bib_ibi与后面某个bjb_jbj的异或最大值

然后前缀/后缀max递推

枚举断点iii,直接利用prei+sufi+1pre_i+suf_{i+1}prei+sufi+1更新答案

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define int long long
#define maxn 400005
int trie[maxn * 30][2];
int a[maxn], b[maxn], c[maxn], pre[maxn], suf[maxn];
int n, cnt;void insert( int x ) {int now = 0;for( int i = 29;~ i;i -- ) {int k = x >> i & 1;if( ! trie[now][k] ) trie[now][k] = ++ cnt;now = trie[now][k];}
}int query( int x ) {int now = 0, ans = 0;for( int i = 29;~ i;i -- ) {int k = x >> i & 1;if( trie[now][k ^ 1] )ans += 1 << i, now = trie[now][k ^ 1];elsenow = trie[now][k];}return ans;
}signed main() {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ )scanf( "%lld", &a[i] );for( int i = 1;i <= n;i ++ )b[i] = a[i] ^ b[i - 1];for( int i = n;i;i -- )c[i] = c[i + 1] ^ a[i];insert( 0 );for( int i = 1;i <= n;i ++ ) {pre[i] = max( pre[i - 1], query( b[i] ) );insert( b[i] );}memset( trie, 0, sizeof( trie ) );cnt = 0;insert( 0 );for( int i = n;i;i -- ) {suf[i] = max( suf[i + 1], query( c[i] ) );insert( c[i] );}int ans = 0;for( int i = 1;i < n;i ++ )ans = max( ans, pre[i] + suf[i + 1] );printf( "%lld\n", ans );return 0;
}

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

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

相关文章

H - Prince and Princess 计蒜客 - 42402

H - Prince and Princess 计蒜客 - 42402 题意: 你现在要寻找公主&#xff0c;有三种人&#xff0c;第一种是说真话的人(至少为1&#xff0c;因为公主是说真话的人)&#xff0c;第二种人是只会说假话的&#xff0c;第三种是胡说八道的(说的话真假都有可能)。现在给你三种人的…

模板:min-max容斥离散随机变量的几何分布(洛谷P3175:[HAOI2015]按位或)

前言 见到一道神题&#xff0c;学会两个知识点… 都是数学。 min-max容斥 给出式子&#xff1a; max⁡(S)∑T⊂S(−1)∣T∣1min⁡(T)\max(S)\sum_{T\sub S}(-1)^{|T|1}\min(T)max(S)T⊂S∑​(−1)∣T∣1min(T) min⁡(S)∑T⊂S(−1)∣T∣1max⁡(T)\min(S)\sum_{T\sub S}(-1)^…

杭电多校杂题收录

前言 和学长学弟一起打的hdu多校&#xff0c;打的很菜没啥难题收录&#xff0c;因为难的我都不会做。 正题 hdu7152-Copy 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid7152 题目大意 nnn个数字的序列aaa&#xff0c;mmm次操作&#xff0c;每次将一段[l,r][l,r][l,r…

.NET Core中的验证组件FluentValidation的实战分享

今天有人问我能不能出一篇FluentValidation的教程&#xff0c;刚好今天在实现我们的.NET Core实战项目之CMS的修改密码部分的功能中有用到FluentValidation&#xff0c;所以就以修改用户密码为实例来为大家进行一下ASP.NET Core中的验证组件FluentValidation的实战分享&#xf…

笛卡尔树详解带建树模板及例题运用(Largest Submatrix of All 1’s,洗车 Myjnie,Removing Blocks,SPOJ PERIODNI)

文章目录笛卡尔树介绍例题Largest Submatrix of All 1’s应用「POI2015」洗车 Myjnie[AGC028B] Removing BlocksSPOJ PERIODNI笛卡尔树 介绍 笛卡尔树是一种数据结构&#xff0c;每个点由两个值&#xff0c;键值key和权值val&#xff0c;组成 其键值满足二叉树性质 即点的左子…

K - Triangle 计蒜客 - 42405

K - Triangle 计蒜客 - 42405 题意&#xff1a; 给你一个三角形的三点&#xff0c;再给你三角形边上一个点&#xff0c;让你求另一个点(也要在三角形上)&#xff0c;使得平分三角形的面积 题解: 计算几何 三角形的三边ab&#xff0c;ac&#xff0c;bc 如果点p在ab上&#x…

P2508-[HAOI2008]圆上的整点【数学】

正题 题目链接:https://www.luogu.com.cn/problem/P2508 题目大意 一个在(0,0)(0,0)(0,0)的圆心&#xff0c;半径为rrr&#xff0c;求圆有多少个整点。 1≤r≤21091\leq r\leq 2\times 10^91≤r≤2109 解题思路 设这个点为(x,y)(x,y)(x,y)&#xff0c;那么有x2y2r2x^2y^2r^2…

如何为ASP.NET Core设置客户端IP白名单验证

本篇博文中展示了如何在ASP.NET Core应用程序中设置IP白名单验证的3种方式。你可以使用一下3种方式&#xff1a;使用中间件检查每个请求的远程IP地址使用Action过滤器为指定的Controller或action方法添加针对远程IP地址的检查使用IPageFilter为Razor Pages应用添加针对远程IP地…

CodeForces - 140C New Year Snowmen

CodeForces - 140C New Year Snowmen 题意&#xff1a; 现在来做雪人&#xff0c;每个雪人由三个不同大小的雪球构成&#xff1a;一个大的&#xff0c;一个中等的&#xff0c;一个小的。现在有 n 个雪球半径分别为 r1, r2, …, rn. 为了做雪人&#xff0c;三个雪球的大小必须…

洛谷P4389:付公主的背包(多项式、生成函数)

对于一些生成函数累乘的题目&#xff0c;也许可以通过求 ln⁡\lnln 转化为累加问题从而完成简化。 解析 不难写出对于单个物品 kkk 的生成函数&#xff1a; ∑i1xVi11−xVK\sum_{i1}x^{Vi}\frac{1}{1-x^{V_K}}i1∑​xVi1−xVK​1​ 那么答案的生成函数就是所有物品的函数的卷积…

数据结构之fhq-treap——Chef and Sets,[HNOI2012]永无乡,Play with Chain,[NOI2005]维修数列(结构体版代码)

因为非常板&#xff0c;所以主要是代码Tyvj 1728 普通平衡树Chef and Sets[HNOI2012]永无乡Play with Chain[NOI2005]维修数列题目很水&#xff0c;所以可能会出现代码部分细节出锅&#xff0c;但确实这些代码是能过得 还请多多包涵 Tyvj 1728 普通平衡树 luogu3369 #include…

让ASP.NET Core支持GraphQL之-GraphQL的实现原理

众所周知RESTful API是目前最流行的软件架构风格之一&#xff0c;它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁&#xff0c;更有层次&#xff0c;更易于实现缓存等机制。RESTful的优越性是毋庸置疑的&#xff0c;不过GraphQL也可以作为一种补充&am…

CodeForces 1514A Perfectly Imperfect Array

CodeForces 1514A Perfectly Imperfect Array 题意&#xff1a; 给你n个数&#xff0c;是否存在一个数不是平方数 题解&#xff1a; 先开方&#xff0c;转int&#xff0c;判断是否等于平方 代码&#xff1a; #include<bits/stdc.h> #define debug(a,b) printf(&quo…

另一个博客

在博客园搞了个博客&#xff0c;目前来说两边会同时更新的。 有些题目不放出来&#xff0c;都写在来博客园那边&#xff0c;虽然你们也不知道密码 链接:https://www.cnblogs.com/QuantAsk/

洛谷P4173:残缺的字符串(FFT、通配符匹配)

解析 通配符匹配的经典题。 设单词串为 AAA,文章串为 BBB。 把 AAA 翻转一下&#xff0c;判断问题就能转化为一个卷积的形式&#xff1a; F(p)&i0m−1match(Ai1,Bp−i)F(p)\&_{i0}^{m-1}match(A_{i1},B_{p-i})F(p)&i0m−1​match(Ai1​,Bp−i​) match(a,b)match(…

[2021-09-02 contest]CF1251C,可达性统计(bitset优化dp),Boomerang Tournament(状压dp),小蓝的好友(mrx)(treap平衡树)

文章目录CF1251C Minimize The Integeracwing164&#xff1a;可达性统计Facebook Hacker Cup 2016 Round 1 Boomerang Tournament[Zjoi2012]小蓝的好友(mrx)CF1251C Minimize The Integer ………………… 给你一个大整数aaa&#xff0c;它由nnn位数字&#xff0c;也可能有前导…

Entity Framework 的一些性能建议

点击上方蓝字关注“汪宇杰博客”这是一篇我在2012年写的老文章&#xff0c;至今适用&#xff08;没错&#xff0c;我说的就是适用于EF Core&#xff09;。因此使用微信重新推送&#xff0c;希望能帮到大家。自从我用了EF&#xff0c;每次都很关心是否有潜在的性能问题。所以每次…

AND 0, Sum Big CodeForces - 1514B

AND 0, Sum Big CodeForces - 1514B 题意&#xff1a; 构造一个含n个k位二进制数的序列&#xff0c;使得序列中所有数按位与的结果为0&#xff0c;且序列和最大&#xff0c;求构造方案数。 题解&#xff1a; 对于n个数的每一位&#xff0c;都至少有个0&#xff0c;这样可以…

CF438E:The Child and Binary Tree(生成函数)

解析&#xff1a; 设计 fif_ifi​ 表示权值为 iii 的方案数&#xff0c;f01f_01f0​1。 枚举根节点权值&#xff0c;可以写出转移&#xff1a; fn∑gk∑ififn−k−i∑ijknfifjgkf_n\sum g_k\sum_{i}f_if_{n-k-i}\sum_{ijkn}f_if_jg_kfn​∑gk​i∑​fi​fn−k−i​ijkn∑​fi​…

[2021-09-04 AtCoder Beginner Contest 217] 题解

文章目录A - Lexicographic OrderB - AtCoder QuizC - Inverse of PermutationD - Cutting WoodsE - Sorting QueriesF - Make PairG - Groups网址链接A - Lexicographic Order 签到题 #include <cstdio> #include <iostream> using namespace std; int main() {…