首页 > 其他分享 >字典树 计数问题(含 2022 icpc杭州 K)

字典树 计数问题(含 2022 icpc杭州 K)

时间:2024-10-16 22:51:18浏览次数:10  
标签:string int long icpc 单词 2022 计数问题 字典 逆序

//最近学了字典树,补一下

1.概念和实现

首先,字典树是一棵树(废话),边表示字母,从根到叶子节点所有边的顺序组合表示字目排列顺序。

看一下图明白很多:

例如:abc这个字母排序(或者说“单词”),可以用1->2->5->8这条路径表示。有个性质就是:同一个单词的末尾节点标号是唯一的。比如以6为末尾的“单词”只能是ac,不可能是bc。相当于每个点都要连自己的新边。

那么现在来实现字典树的插入和搜索。插入就是把单词插入树中,查找就是查找某单词出现的次数。

代码模板如下:

//ch[a,b]:在a这个节点接表示b字母的边
//cnt[a]:以节点a为末尾的“单词”的数量

#include<iostream>
using namespace std;
const int N=10000010;

int cnt[N],ch[N][27],idx;
strint s;

void insert(string s){
	int p=0;
	for(int i=0;i<s.size();i++){
		int g=s[i]-'a';
		if(!ch[p][g])ch[p][g]=idx++;
		p=ch[p][g];
	}
	cnt[p]++;
}

int query(string s){
	int p=0;
	for(int i=0;i<s.size();i++){
		int g=s[i]-'a';
		if(!ch[p][g])return 0;
		p=ch[p][g];
	}
	return cnt[p];
}

int main()
{
	cin>>s;
	//...略
	return 0;	
}

字典树可以解决很多问题。我目前遇到的是两种,接下来再遇到就再整理:

1.记录某单词或排列的出现次数                         

2.记录不同排列从哪个字母开始有差别(比如这题)

2.例题


Problem - K - Codeforcesicon-default.png?t=O83Ahttps://codeforces.com/group/w6iGs8kreW/contest/552941/problem/K

K. Master of Both

time limit per test

1 s

memory limit per test

1024 MB

Professor Hui-Bot is the master of string theory and advanced data structures, so he came up with an interesting problem. Given a sequence of nn strings consisting of only lowercase English letters, how many inversions are there in this sequence when the strings are compared by lexicographical order?

As the most extraordinary student of Hui-Bot, Putata and Budada mastered superb string theory and advanced data structure skills respectively, and they solved this problem together with ease. However, there are qq different parallel universes, where the characters in the alphabet are not appearing in the original order.

Formally, the alphabet in each universe is a string, which is a permutation of the 2626 lowercase English letter, denoting the order each character appears.

A string aa is lexicographically smaller than a string bb if and only if one of the following holds:

  • aa is a prefix of bb, but a≠ba≠b;
  • in the first position where aa and bb differ, the string aa has a letter that appears earlier in the alphabet than the corresponding letter in bb.

The number of inversions in a sequence aa of length nn is the number of ordered pairs (i,j)(i,j) such that 1≤i<j≤n1≤i<j≤n, aj<aiaj<ai.

Please help Putata and Budada in each universe to solve the problem.

Input

The first line of the input contains two integers n,qn,q (1≤n≤5×1051≤n≤5×105, 1≤q≤5×1041≤q≤5×104), denoting the length of the sequence.

For the following nn lines, the ii-th line contains a string sisi (1≤|si|≤1061≤|si|≤106). It is guaranteed that the string consists of only lowercase English letters, and ∑i=1n|si|≤106∑i=1n|si|≤106.

For the following qq lines, each line contains a string tt, denoting the alphabet in one universe. It is guaranteed that tt is a permutation of 2626 lowercase English letters.

Output

Output qq lines, denoting the answer in qq universes.


思路:这题一开始是用树状数组暴力求逆序对个数的,但 毫无疑问地 t了。主要是每次都要排序,这就nlogn了,然后还有多组,包t。当时其实我就有这个想法,主要是 决定某两个单词是否逆序的字母排序是确定的,所以我们其实只需要把决定逆序的字母全取出来(用一个26*26的二维数组存储),每次给定一个排序原则之后,再用一个26*26的循环来看一下每一组是否真的逆序了。这样就不会超时了。

但问题就出在怎么找这些逆序对上面。暴力解方法不会,就卡住了。

其实就是用的 字典树。每一层看看还存了多少其他不同字母。这就用到了字典树的性质:同一节点上面所经过的路径一定是一样的,不存在有多个路径到达一个节点的情况

还有一个注意的点,就是ans要开unsigned long long。这个罚了我好几发。

看一下代码吧~

#include<iostream>
#include<cstring>
using namespace std;
#define int long long 
typedef unsigned long long ull;
 
const int N=1e6+100;
int n,q,ch[N][30],idx,sor[N];
string s[N],g;
char r='a'-1;
int cnt[100][100];//cnt[a][b]表示由于a在b前而引起的逆序对;
int num[N][30];
 
void count(string s){
	int p=0;
	for(int i=0;i<s.size();i++){
		int g=s[i]-'a'+1;
		for(int i=0;i<=26;i++){
			if(i==g)continue;
			if(ch[p][i])cnt[i][g]+=num[p][i];
		}
		if(!ch[p][g])ch[p][g]=++idx;
		num[p][g]++;
		p=ch[p][g];
	}
}
 
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]+=r;
		count(s[i]);
	}
	while(q--){
		idx=0;
		ull ans=0;
		cin>>g;
		sor[0]=0;
		for(int i=0;i<g.size();i++){
			sor[g[i]-'a'+1]=i+1;
		}
		for(int i=0;i<=26;i++){
			for(int j=0;j<=26;j++){
				if(sor[i]>sor[j])ans+=cnt[i][j];
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

标签:string,int,long,icpc,单词,2022,计数问题,字典,逆序
From: https://blog.csdn.net/2301_81888203/article/details/142993311

相关文章

  • ICPC WF 2022 2023 Bridging the Gap 过桥
    https://qoj.ac/problem/8683https://loj.ac/p/6937是个十足的DP题。刷完了YeahPotato的DP博客,你觉得有什么方法能套进来呢?前面“基于特殊结构的技巧”没有一个能用。如何分析性质?分析样例:1238996991088345明显先排序。3456888999910猜想......
  • 20222315 2024-2025-1 《网络与系统攻防技术》实验二实验报告
    1.实验内容1.使用netcat进行虚拟机和主机的连接,cron启动周期性定时任务。2.使用socat让虚拟机操作主机,并调用提前准备的程序,启动任务计划。3.使用MSFmeterpreter(或其他软件)生成后门程序,利用ncat传送到主机让主机运行后门程序,虚拟机获取主机shell。4.使用MSFmeterpreter(或其他......
  • 故障5:2022年1月1日所有邮件不能发送接收(Email Stuck in Exchange On-premises Transpo
    凯中故障5:2022年1月1日所有邮件不能发送接收(EmailStuckinExchangeOn-premisesTransportQueues)https://techcommunity.microsoft.com/t5/exchange-team-blog/email-stuck-in-exchange-on-premises-transport-queues/ba-p/3049447https://social.microsoft.com/Forums/zh-C......
  • 【ICPC】The 2021 ICPC Asia Shanghai Regional Programming Contest I
    SteadilyGrowingSteam#动态规划#背包#枚举题目描述AliceenjoysplayingacardgamecalledSteadilyGrowingSteam(asknownasSGS).Inthisgame,eachplayerwillplaydifferentrolesandhavedifferentskills.Playersgetcardsfromthedeckandu......
  • 【ICPC】The 2021 ICPC Asia Shenyang Regional Contest J
    LuggageLock#搜索#枚举题目描述EileenhasabigluggageandshewouldpickalotofthingsintheluggageeverytimewhenA-SOULgoesoutforashow.However,iftherearetoomanythingsintheluggage,the4-digitpasswordlockontheluggagewill......
  • 【ICPC】The 2021 ICPC Asia Shanghai Regional Programming Contest G
    EdgeGroups#树形结构#组合数学#树形dp题目描述Givenanundirectedconnectedgraphofnnnverticesandn......
  • 【ICPC】The 2021 ICPC Asia Shanghai Regional Programming Contest H
    LifeisaGame#最小生成树#重构树#图论#贪心题目描述Agoodproblemshouldhaveaconcisestatement.Youaregivenanarrayaaaoflength......
  • [SWPUCTF 2022 新生赛]1z_unserialize
    <?phpclasslyh{public$url='NSSCTF.com';public$lt;public$lly;function__destruct(){$a=$this->lt;$a($this->lly);//这里相当于(this->lt)(this->lly)即lt(lly)。}......
  • 20222301 2024-2025-1 《网络与系统攻防技术》实验二实验报告
    1.实验内容本次实验主要围绕渗透测试与远程执行控制展开,通过不同工具和技术手段实现了对目标主机的深入渗透与监控。实验内容可以概括为以下几个方面:1.远程Shell获取:实验首先通过`netcat`和`cron`定时任务,以及`socat`与Windows任务计划相结合的方式,实现了对目标主机的远程Shell......
  • 2022 CCPC 威海站
    写在前面时间复杂度与数据范围的关系计算机1秒大约能执行5e8次计算,假设时间限制为1秒,时间复杂度和数据范围对应如下:O(n)的算法能解决的数据范围在n<=1e8O(nlogn) 的算法能解决的数据范围在n<=1e6O(n^2) 的算法能解决的数据范围在n<=5e3O(n^3) 的算法......