Template _ a estrutura de dados subjacente (a)

lista única

 #include <iostream>
 
 using namespace std;
 
 const int N = 100010;
 
 int head , e[N] , ne[N] , idx;
 
 //插入到头接待你 
 void add_to_head(int x)
{
    e[idx] = x;
 	ne[idx] = head; //新节点指向head之前指向的点 
 	head = idx;     //让head指向新加入的结点 
 	idx++;
}
 
 void add(int k  ,int x)
 {
 	e[idx] = x;
 	ne[idx] = ne[k];
 	ne[k] = idx;
 	idx++; 	
 } 

void remove(int k)
{
	ne[k] = ne[ne[k]];
}
 int main()
 {
 	head = -1 , idx = 0;
 	
 	int m;
 	cin >> m;
 	
 	while(m -- )
 	{
 		int k ,x;
 		char op;
 		
 		cin >> op;
 		if(op == 'H')
 		{
 			cin >> x;
 			add_to_head(x); 
		}
		else if(op == 'D')
		{
			cin >> k;
			if(!k) head = ne[head];   //头结点特判 k=0 
			remove(k - 1);
		}
		else
		{
			cin >> k >> x;
			add(k - 1 , x);
		}
	}
	
	for(int i = head ; i != -1 ; i =ne[i])
	{
		cout << e[i] << " ";
	}
	cout << endl;
  	
 	return 0;
 }

lista duplamente ligada

#include <iostream>

using namespace std;

const int N = 100010;

int m;
int e[N] , l[N] , r[N] ,idx;

void init()
{
	r[0] = 1;    //0表示左端点,1表示右端点 
	l[1] = 0;
	idx = 2; 
}

void add(int k , int x)
{
	e[idx] = x;
	r[idx] = r[k];
	l[idx] = k;
	
	l[r[k]] = idx;
	r[k] = idx;
} 

void remove(int k)
{
	r[l[k]] = r[k];
	l[r[k]] = l[k];
}

int main()
{
	
	return 0;
}

pilha monótona

#include <iostream>

using namespace std;

const int N = 100010;

int n ;
int stk[N] , tt;

int main()
{
	cin >> n;
	
	for(int i = 0 ; i < n ; i++)
	{
		int x;
		cin >> x;
		
		while(tt && stk[tt] >= x) tt--;
		if(tt != 0) cout << stk[tt] << " ";
		else cout << -1 << " ";	
		
		stk[ ++ tt] = x; 
	}

	return 0;
} 

fila monótona (janela deslizante)

#include <iostream>

using namespace std;

const int N = 1000010;

int n , k;
int a[N] , q[N];    //a存值,q是单调队列 

int main()
{
	scanf("%d%d" , &n , &k);
	for(int i = 0 ; i < n ; i++ )  scanf("%d" , &a[i]);
	
	int hh = 0 , tt = -1;
	for(int i= 0 ; i < n ; i++)
	{
		//判断队头是否已经划出窗口
		if(hh <= tt && i - k + 1 > q[hh]) hh++;   //q[hh]存放的下标 
		while(hh <= tt && a[q[tt]] >= a[i])  tt--;  //之前的数字比当前的大,出队 
		
		q[ ++ tt ] = i;
		if(i >= k - 1) printf("%d " , a[q[hh]]);
	}
	puts(" ");
	
	hh = 0 , tt = -1;                 //队列要清空 
	for(int i= 0 ; i < n ; i++)
	{
		//判断队头是否已经划出窗口
		if(hh <= tt && i - k+ 1 > q[hh]) hh++;   //q[hh]存放的下标 
		while(hh <= tt && a[q[tt]] <= a[i])  tt--;  //之前的数字比当前的小,出队 
		
		q[ ++ tt ] = i;
		if(i >= k - 1) printf("%d " , a[q[hh]]);
	}
	puts(" ");
	 
	return 0;
}

km²

#include <iostream>

using namespace std;

const int N = 10010 , M  = 100010;

int n , m;
char p[N] , s[M];
int nex[N];

int main()
{
	cin >> n >> p + 1 >> m >> s + 1;    //p是子串 , s是模式串 
	
	//求next的过程
	for(int i = 2 , j = 0 ; i <= n ; i++)
	{
		while(j && p[i] != p[j + 1]) j = nex[j];
		if(p[i] == p[j + 1]) j++;
		nex[i] = j;
	} 
	
	//kmp匹配过程 
	for(int i = 1 , j = 0 ; i <= m ; i++)
	{
		while(j && s[i] != p[j + 1]) j = nex[j];  //j没有退回起点,
		if(s[i] == p[j + 1]) j++;
		if(j == n)
		{
			printf("%d" , i - n);
			j = nex[j];
			cout << endl << j <<endl; 
		}
	}
	return 0 ;
} 

Trie

#include <iostream>

using namespace std;

const int N = 100010;

int son[N][26] , cnt[N] , idx;
char str[N];

void insert(char str[])
{
	int p = 0 ;
	for(int i = 0 ; str[i] ; i++)
	{
		int u = str[i] - 'a';
		if(!son[p][u])  son[p][u] = ++idx;
		p = son[p][u];	
	}
	cnt[p] ++;   //给末尾的结点打标记 
}

int query(char str[])
{
	int p = 0 ;
	for(int i = 0 ; str[i] ; i++)
	{
		int u = str[i] - 'a';
		if(!son[p][u]) return 0;
		p = son[p][u];
	}
	return cnt[p];
}

int main()
{
	int n;
	scanf("%d" , &n);
	while(n--)
	{
		char op[2];
		scanf("%s%s" , op , str);
		if(op[0] == 'I') insert(str);
		else printf("%d\n" , query(str));
		
	}
	return 0;
} 

////5
//I abc
//Q abc
//Q ab
//I ab
//Q ab
Publicado 12 artigos originais · ganhou elogios 0 · visualizações 109

Acho que você gosta

Origin blog.csdn.net/qq_45244489/article/details/105130118
Recomendado
Clasificación