Acwing 第二章 数据结构
单调队列
154. 滑动窗口
用一个队列维护窗口里面的所有值
当即将入队的队列比队尾元素小时,就让队尾元素出队,循环直到大于等于队尾元素时,停止,因为没有用
求最大值与该思想类似
#include
#include
#include
using namespace std;
const int N = 1e6 + 10;
int n,k;
int a[N];
int q[N];//队列存储的是下标
int main()
{
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i ++ )
{
cin>>a[i];
}
int hh = 0,tt = -1;
for (int i=0;i k) hh++; //维护当前窗口元素个数与k一致
while(hh<=tt && a[i] <= a[q[tt]]) tt--; //删去冗余元素,注意是从队尾删除
q[++tt] = i; //新元素入队
if(i+1>=k) cout< k) hh++;
while(hh<=tt && a[i] >= a[q[tt]]) tt--;
q[++tt] = i;
if(i+1>=k) cout<
字典树(Trie)
835. Trie字符串统计
Trie:高效的存储和查找字符串集合的数据结构
#include
#include
#include
#include
using namespace std;
const int N = 2e4+10;
int son[N][26],idx;//son数组表示字典树,idx表示层数索引
int cnt[N];//以当前结点结尾的单词数量
char x[N];
char op[2];
void insert(char s[])
{
int cur = 0;//表示当前位于第几层
for(int i=0;s[i]!='\0';i++)
{
int t = s[i] - 'a';
if(!son[cur][t]) son[cur][t] = ++idx; //没有路径就创造路径,注意是++idx
//idx是下一字母的层数
cur = son[cur][t];
}
cnt[cur]++;//更新以该结点结尾的单词数量
}
int query(char s[])
{
int cur = 0;//表示当前位于第几层
for(int i=0;s[i]!='\0';i++)
{
int t = s[i] - 'a';
if(!son[cur][t]) return 0;//不存在路径,直接返回0
cur = son[cur][t];
}
return cnt[cur];
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i ++ )
{
cin>>op>>x;
if(op[0] == 'I')
{
insert(x);
}
else cout<
并查集
240. 食物链
带权并查集
#include
#include
#include
using namespace std;
const int N = 50005;
int n,k,c,x,y;
int p[N],d[N];
int ans;
int find(int x)
{
int t = p[x];
if(p[x]!=x)
{
p[x] = find(p[x]);
d[x] += d[t]; //维护距离,find前表示到父节点的距离,find后表示到祖宗结点的距离
}
return p[x];
}
int main()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
}
while(k--)
{
cin>>c>>x>>y;
if(x>n||y>n)
{
++ans;
continue;
}
int px = find(x),py = find(y);
if(c==1) //同类,距离取余3为0
{
if(px == py && (d[x] - d[y]) % 3 != 0) ans++; //同一集合但距离mod3不为0,假话
else if(px!=py) //不同集合,则是真话,合并它们并用距离表示同类关系
{
p[px] = py;
d[px] = d[y] - d[x];
}
}
else //x吃y,距离取余3为1
{
if(px == py && (d[x] - d[y] - 1) % 3 !=0) ans++; //同一集合但距离mod3不为1,假话
else if(px != py) //不同集合,则是真话,合并它们并用距离表示捕食关系
{
p[px] = py;
d[px] = d[y] - d[x] + 1;
}
}
}
cout<
字符串哈希
841. 字符串哈希
#include
#include
#include
using namespace std;
const int N = 1e5 + 10,P = 131;
typedef unsigned long long ULL;
ULL h[N],p[N];
int n,m;
char str[N];
ULL get(int l,int r)
{
return h[r] - h[l-1] * p[r-l+1]; //取区间字符串的哈希值 h[r] - h[l-1] * p^(r-l+1)
}
int main()
{
scanf("%d%d%s", &n, &m,str+1);
p[0] = 1;
for (int i = 1; i <= n; i ++ )
{
p[i] = p[i-1] * P; //预处理P的n次幂
h[i] = h[i-1] * P + str[i]; //计算哈希值
}
while (m -- )
{
int l1,r1,l2,r2;
scanf("%d%d%d%d", &l1, &r1,&l2,&r2);
if(get(l1,r1) == get(l2,r2)) puts("Yes");
else puts("No");
}
return 0;
}