链接 : C-联想标语_2023年第三届 “联想杯”全国高校程序设计在线邀请赛暨第五届上海理工大学程序设计竞赛(同步赛) (nowcoder.com)
题意 : n个操作, 每次给你一个u,和 t 串,u==1 时,如果给定的字符串中有“Lenovo”答案加一, u==2时要删掉以这个串为前缀的前缀,输出有多少个串还包含“Lenovo”(不是真的删掉)
前缀字符串可以想到tire和字符串哈希,笔者只放个tire
#include<bits/stdc++.h> using namespace std; using ull = unsigned long long; using ll = long long; using PII = pair<int,int>; #define IOS ios::sync_with_stdio(false),cin.tie(0) #define endl "\n" #define pb push_back const int N=1e6+10; const int INF=0x3f3f3f3f; const int mod=998244353; struct node { int son[26]; int siz; }s[N]; int tot; int res; int main() { IOS; int n; cin >> n; for(int i = 1; i <= n; i ++) { int op; string t; cin >> op >> t; int len = t.size(); if(op == 1) { int pos = -1; for(int k = len - 6; k >= 0 && pos == -1; k --)//至少存在一个,即保证最后一个联想字符串不会被删除,就倒着找pos if(t.substr(k, 6) == "lenovo") pos = k, res ++; //pos = t.rfind("lenovo");//可以直接用rfind函数 //if(pos != -1) res ++; int now = 0; for(int k = 0; k < len; k ++)//构建字典树 { int c = t[k] -'a'; if(!s[now].son[c]) s[now].son[c] = ++ tot; now = s[now].son[c]; if(k >= pos && pos != -1)//前缀字符贡献 s[now].siz ++; } //cout << pos << endl; } else if(op == 2) { int num = 0, now = 0; for(int k = 0; k < len; k ++)//查找字典树 { int c = t[k] - 'a'; if(!s[now].son[c]) break;//有没有出现过的字符直接无效 now = s[now].son[c]; if(k + 1 == len) num += s[now].siz;//如果包含在前缀里,最后一定是联想字符串的某个字符,否则就不是前缀,只算尾部的贡献,防止重复 } //cout << num << endl; cout << res - num << endl; } } return 0; }
标签:son,int,联想,pos,++,using,标语,now From: https://www.cnblogs.com/ZouYua/p/17871479.html