题意

给出n个字符串,每个字符串有一个权值wi 有q个操作,操作有两种 1 x y 将字符串x的权值变为y 2 x 查询操作,输出以字符串x为后缀,且权值小于等于wx的字符串个数。其中n<=1000 每个字符串长度<=1000 询问q<=80000。

分析

n并不大,但是q太大了。如果暴力的话,每次查询都是o(n*len)的,肯定不行。

等等,谁说不行?我试试 emmm。。。爆过去了????下面是瞎几把爆的代码:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std;
const int maxn=+;
int len[maxn],w[maxn];
char s[maxn][maxn];
int T,n,q; int main(){
scanf("%d",&T);
for(int t=;t<=T;t++){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%s",s[i]);
scanf("%d",&w[i]);
len[i]=strlen(s[i]);
}
scanf("%d",&q);
int opt;
for(int i=;i<=q;i++){
scanf("%d",&opt);
if(opt==){
int x,y;
scanf("%d%d",&x,&y);
w[x]=y;
}else if(opt==){
int x;
scanf("%d",&x);
int ans=;
for(int j=;j<=n;j++){
if(w[j]>w[x])continue;
if(len[j]<len[x])continue;
bool ok=;
for(int k=len[j]-,l=len[x]-;l>=;k--,l--){
if(s[x][l]!=s[j][k]){
ok=;
break;
}
}
if(ok){
ans++;
// cout<<j<<endl;
}
}
printf("%d\n",ans);
}
}
}
return ;
}

好吧好吧,上面那个不算,我们重新来想···

后缀嘛,后缀数组?咳,我就知道名字而已不会。。想点会的。。

字典树行不行?我们只要把字符串倒着插进去就可以用统计前缀的方法来统计后缀了。

w这个限制怎么办?

我们在字典树上每一个字符串结尾维护一个vector···这样··时间复杂度是多少?均摊下应该是···可以的···吧?

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int maxn=+;
int ch[maxn*maxn][],W[maxn];
char s[maxn][maxn];
int val[maxn*maxn];
vector<int>G[maxn*maxn];
int T,n,q,sz;
void insert(char *s,int w){
int len=strlen(s);
int u=;
for(int i=;i<len;i++){
int id=s[i]-'a';
if(!ch[u][id]){
ch[u][id]=++sz;
}
u=ch[u][id];
}
G[u].push_back(w);
return ;
}
void tra(int u){
/* if(G[u].size()!=0){
for(int i=0;i<G[u].size();i++){
printf("%d ",G[u][i]);
}
return;
}*/
for(int i=;i<;i++){
if(ch[u][i]){
printf("%c",i+'a');
tra(ch[u][i]);
}
}
return;
}
int ans;
void check(int u,int k){
if(G[u].size()){
for(int i=;i<G[u].size();i++){
if(W[G[u][i]]<=W[k]){
ans++;
}
}
}
for(int i=;i<;i++){
if(ch[u][i])
check(ch[u][i],k);
}
return;
}
void solve(int k){
int u=;
ans=;
for(int i=strlen(s[k])-;i>=;i--){
int id=s[k][i]-'a';
if(!ch[u][id]){
return ;
}
u=ch[u][id];
}
check(u,k);
return ;
}
int main(){
scanf("%d",&T);
for(int t=;t<=T;t++){
scanf("%d",&n);
for(int i=;i<=*;i++)G[i].clear();
memset(val,,sizeof(val));
memset(ch,,sizeof(ch));
sz=;
char s1[maxn];
int x;
for(int i=;i<=n;i++){
scanf("%s%d",s[i],&W[i]);
for(int j=;j<strlen(s[i]);j++){
s1[j]=s[i][strlen(s[i])--j];
}
s1[strlen(s[i])]='\0';
insert(s1,i);
}
// tra(0); scanf("%d",&q);
for(int i=;i<=q;i++){
int opt;
scanf("%d",&opt);
if(opt==){
int x,y;
scanf("%d%d",&x,&y);
W[x]=y;
}else if(opt==){
int x;
scanf("%d",&x);
solve(x);
printf("%d\n",ans);
}
}
}
return ;
}

最新文章

  1. 使用cmake自动构建工程
  2. C# 实现 Excel文件的数据导入
  3. Excel VBA自动添加证书(二)
  4. git clone简介
  5. Android弱网测试中关于网络检测的一些借鉴方法
  6. lines---hdu5124(离散化+数组模拟)
  7. UVALive 7456 Least Crucial Node (并查集)
  8. POJ3026——Borg Maze(BFS+最小生成树)
  9. Android关机流程源码分析
  10. Android实现渐显按钮的左右滑动效果
  11. Flex 各种校验
  12. win7自动关机方法
  13. 在IDEA中设置命令行参数
  14. 关于java前端入门的一些简单的看法
  15. ant jmeter 优化报告
  16. vue-router 懒加载优化
  17. Java——poi读取Excel文件
  18. cc1: warnings being treated as errors解决办法
  19. windows上使用clang编译程序
  20. c# 数据库通用类DbUtility

热门文章

  1. spring 和springmvc 在 web.xml中的配置
  2. ORM版,学生管理系统02
  3. Raspberry Pi 配置
  4. session不一定非得要cookie开启才能使用。也可以使用get传递参数
  5. CMCC有限的访问权限如何解决
  6. NNI (Neurol Network Intelligence) 是微软开源的自动机器学习工具
  7. [BZOJ5297][CQOI2018]社交网络
  8. LA2572 Viva Confetti
  9. django的表与表之间的关系详细讲解
  10. Java开发前期准备工作