首页 > 其他分享 >P10469 后缀数组(Hash+二分)

P10469 后缀数组(Hash+二分)

时间:2024-09-14 09:46:51浏览次数:1  
标签:typedef return 后缀 P10469 long int ull Hash hash

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef vector<string> VS;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
inline int log_2(int x) {return 31-__builtin_clz(x);}
inline int popcount(int x) {return __builtin_popcount(x);}
inline int lowbit(int x) {return x&-x;}
const ull P=131,N=3e5+3;//根据经验进制P取为131不易冲突
ull h[N],p[N];//ull相当于一个数对2^64取模,p数组里存的是进制次幂运算预处理的结果
char ch[N];
int SA[N];
int n;
ull _hash(int l,int r)
{
    return h[r]-h[l-1]*p[r-l+1];//处理h数组时将第一位字符作为最高位处理
    //故此时要运算出h[r]-h[l-1]的哈希值需要将h[l-1]乘P的r-l+1次
}
void init()
{
	h[0]=0,p[0]=1;
    for(int i=1;i<=n;++i)
    {
        h[i]=h[i-1]*P+ch[i];//用的是ascii码参与运算
        p[i]=p[i-1]*P;
    }
}

int find_pos(int x,int y)
{
	//返回相同的最大长度
	auto check = [&](int M)->bool
	{
		if(!M) return true;
		if(x+M-1>n||y+M-1>n) return false;
		return _hash(x,x+M-1)==_hash(y,y+M-1);
	};
	int L = 0, R = min(n-x+1,n-y+1)+1;
	while(L+1<R)
	{
		int M = (L+R)/2;
		if(check(M)) L = M;
		else R = M;
	}
	return L;	
}
bool cmp(int x,int y)
{
	int pos = find_pos(x,y);
	return ch[x+pos] < ch[y+pos];
}
void solve()
{
	scanf("%s",ch+1);
	n = strlen(ch+1);
	init();
	for(int i=1;i<=n;++i) SA[i] = i;
	sort(SA+1,SA+1+n,cmp);
	for(int i=1;i<=n;++i) cout<<SA[i]-1<<" \n"[i==n];
	cout<<"0 ";
	for(int i=2;i<=n;++i) cout<<find_pos(SA[i],SA[i-1])<<" ";
}
int main()
{
	int T = 1;
	//cin>>T;
	while(T--)
	{
		solve();
	}
}

标签:typedef,return,后缀,P10469,long,int,ull,Hash,hash
From: https://www.cnblogs.com/ruoye123456/p/18413366

相关文章

  • P10468 兔子与兔子(Hash)
    #include<bits/stdc++.h>usingnamespacestd;#definexfirst#defineysecondtypedefpair<int,int>PII;typedeflonglongll;typedefunsignedlonglongull;typedefunsignedintuint;typedefvector<string>VS;typedefvector<int>......
  • Hash Table 哈希表工作原理介绍及C/C++/Python实现
    HashTable哈希表工作原理介绍及C/C++/Python实现哈希表(HashTable),也称为散列表,是一种通过哈希函数将键(Key)映射到表中一个位置以便快速访问记录的数据结构。它提供了非常高效的数据检索、插入和删除操作。哈希表的基本原理是使用一个哈希函数将输入(通常是字符串)转换为一个......
  • P10467 [CCC 2007] Snowflake Snow Snowflakes(Hash)
    #include<bits/stdc++.h>usingnamespacestd;#definexfirst#defineysecondtypedefpair<int,int>PII;typedeflonglongll;typedefunsignedlonglongull;typedefunsignedintuint;typedefvector<string>VS;typedefvector<int>......
  • Hash表实践 —— 两数之和
    目录题目背景解题思路题目背景这个题目用常规的双循环就可以完成。但不是最优解。为什么?看看他的步骤数:N=【3,2,4】求结果为6的两个元素坐标如下,1).3+2=5不等于2).3+4=7不等于3).2+4=6等于,获取坐标【1,2】规律:2个数=1个步骤3个数=3个步骤4个数=6......
  • 黑马面试集合(ArrayList, HashMap)篇笔记整理,结尾附Java的集合相关高频面试题及答案
    集合操作数据的特点-算法复杂度分析数据结构算法复杂度分析为什么要进行复杂度分析?指导编写性能更优的代码评判别人写代码的好坏时间复杂度分析时间复杂度分析:来评估代码的执行耗时的假设每行代码的执行耗时一样:1ms分析这段代码一共执行多少行?3n+3......
  • LinkedHashMap原理详解—从LRU缓存机制说起
    写在前面从一道Leetcode题目说起首先,来看一下Leetcode里面的一道经典题目:146.LRU缓存机制,题目描述如下:请你设计并实现一个满足LRU(最近最少使用)缓存约束的数据结构。实现LRUCache类:LRUCache(intcapacity)以正整数作为容量capacity初始化LRU缓存intget(int......
  • HashMap线程不安全|Hashtable|ConcurrentHashMap
    文章目录常见集合线程安全性HashMap为什么线程不安全?怎么保证HashMap线程安全HashtableConcurrentHashMap引入细粒度锁代码中分析总结小结常见集合线程安全性ArrayList、LinkedList、TreeSet、HashSet、HashMap、TreeMap等都是线程不安全的。HashTable是线程安......
  • HashMap源码分析
    HashMap源码分析在jdk1.8中,HashMap的数据结构如上图所示,是由Node数组+链表/红黑树组成的,每个K-V对保存在一个Node结点中,看一下Node结点的定义,其实就是一个Map.Entry<K,V>的实现类,包括key的hash值,key,value和一个next指针。staticclassNode<K,V>implementsMap.Entry<K,V>{......
  • 树(tree)和哈希算法(Hash)
    树由n个节点组成的有限集。有一个根节点;其他节点只有一个前驱节点,但可以有多个后继节点。叶子节点(终端结点):只有前驱结点没有后继结点结点度:子节点的个数称之为度树的(广)度:树中各节点度的最大值 深度:从根节点到最底层节点的层数森林:n个互不相交的树的集合二叉树:任意一个节点......
  • [ABC250Ex] Trespassing Takahashi
    感觉是很厉害的结论题。题意给你一个带权无向连通简单图\(G=(V,E),|V|=n,|E|=m\)。钦定编号\(1\simk\)的点为关键点。给定\(q\)次询问,每次询问给出\(x,y,t\),表示你需要回答是否存在一条路径,使得从\(x\)出发到\(y\)的路径上相邻两个关键点的距离都不超过\(t\)。保证......