首页 > 其他分享 >【做题日记】

【做题日记】

时间:2022-10-31 14:14:35浏览次数:102  
标签:ch 前缀 int fa inline include 日记

P3294 [SCOI2016]背单词
贪心+Trie+dfs

贪心:对于一个串和他的前缀子串,尽可能把前缀放在前面

把后缀反向插转化为为前缀 trie插一遍
并查集重构树dfs求子树大小
按规则求和

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
const int N=500057;
int n,idx,val[N],tot,size[N],fa[N],id[N];
long long ans;
int ch[N][30];
char s[N];
vector<int>tree[N];
inline int find(int x)
{
	if(x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}

inline void insert(char s[],int num)
{
	int p=0;
	for(int i=strlen(s)-1;i>=0;i--)
	{
		int u=s[i]-'a';
		if(!ch[p][u]) ch[p][u]=++idx;
		p=ch[p][u];
	}
	val[p]=num;
}
inline void remake(int now)
{
	
	for(int i=0;i<26;i++)
	{
		int ver=ch[now][i];
		if(!ver) continue;
	    if(!val[ver])
	    {
	    	fa[ver]=find(now);
		}
	    else
	    {
	    	tree[val[find(now)]].push_back(val[ver]);
		}
		remake(ver);
	}
}
bool cmp(int x,int y)
{
	return size[x]<size[y];
}
inline void make(int now)
{
	size[now]=1;
	for(int i=0;i<tree[now].size();i++)
	{
		make(tree[now][i]);
		size[now]+=size[tree[now][i]];
	}
	sort(tree[now].begin(),tree[now].end(),cmp);
}
inline void dfs(int now)
{
	id[now]=tot++;
	
	for(int i=0;i<tree[now].size();i++)
	{
		ans+=tot-id[now];
		dfs(tree[now][i]);
	}
	
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",s);
		insert(s,i);
	}
	for(int i=1;i<=idx;i++) fa[i]=i;
	remake(0);
	make(0);
	dfs(0);
	printf("%lld",ans);
	return 0;
}

标签:ch,前缀,int,fa,inline,include,日记
From: https://www.cnblogs.com/watasky/p/16844025.html

相关文章

  • 2021-10-22日记
    哎,真是醉了,今天真的是明白一件事儿,越是想贪便宜就越是贪不了便宜。说是今天信用卡有活动,加油中石化五折,于是下班后兴冲冲跑过去了,结果被告知有时间限制,过了晚上五点就没有这......
  • [BUUCTF]第八天训练日记
    文章目录​​[ZJCTF2019]NiZhuanSiWei​​​​[CISCN2019华北赛区Day2Web1]HackWorld​​​​[网鼎杯2018]Fakebook​​​​[极客大挑战2019]HardSQL​​​​[GXYCTF......
  • 算法学习日记10.29
    第一章基础算法(二)高精度高精度加法大整数存储:将数字存到数组里,第一个位置存个位,第二个位置存十位......从A0+B0开始算起,算个位,满十进一易错点:将数字存在字符串里......
  • 【HDLBits刷题日记】08 Karnaugh Map to Circuit
    Kmap1化简卡诺图即可。moduletop_module(inputa,inputb,inputc,outputout);assignout=b|c|a;endmoduleKmap2我是这样化简的。......
  • 算法学习日记10.27
    第一章基础算法(一)上课:理解算法主要思想课后:理解代码模板并且能够快速默写用题目检验重复3-5次就能很好的提升熟练度排序快速排序基于分治思想确定分界点:q[l] ......
  • 【HDLBits刷题日记】07 Multiplexer&Arithmetic adder
    Mux2to1moduletop_module(inputa,b,sel,outputout);assignout=sel?b:a;endmoduleMux2to1v100位和1位的是一样的。moduletop_module(......
  • 【HDLBits刷题日记】06 Basic Gates
    Exams/m2014q4hmoduletop_module(inputin,outputout);assignout=in;endmoduleExams/m2014q4imoduletop_module(outputout);assignout=......
  • 【HDLBits刷题日记】04 Procedures
    Alwaysblock1组合逻辑always块的使用,注意这里的wire和reg综合出来的结果是一样的,这里只是verilog语法导致二者声明不一样。//synthesisverilog_input_versionverilog......
  • vue笔记 11 createElement、Vue3、Vue.config.productionTip = false/true打包时日记
                  面试了解            ......
  • 10月23日:学习日记(函数递归)
    什么是递归?程序调用自身的编程技巧称为递归(recursion)。递归做为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法......