【长郡NOIP2014模拟10.22】字符串查询

2024-05-29 03:08

本文主要是介绍【长郡NOIP2014模拟10.22】字符串查询,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Description

给定n个字符串和q个询问
每次询问在这n个字符串中,有多少个字符串同时满足
1. 字符串a是它的前缀
2. 字符串b是它的后缀

Input

第一行两个数n,q ,表示给定字符串数和询问数
接下来n行每行一个字符串
再接下来q组询问,每组询问2行,分别表示两个字符串a,b,意义上述

Output

q行每行一个数,表示有多少个字符串满足条件

Sample Input

4 2
abc
bac
ac
acc
a
c
ba
ac

Sample Output

3
1
【友情提示】
字符串全部由小写字母a到j组成,行末保证没有多余字符,没有多余的空行,没有空串

Data Constraint

30%数据满足n,q≤1000
另有30%数据满足n,q≤50000,所有询问中a,b串长度丌超过2
100%数据满足n,q≤50000,字符串长度丌超过100,任意两串最长公共前缀较短

Solution

时限很大,意思就是让你排序的
怕被卡的话就把它压成十进制数然后排序(字母只有a~j共10个)
按照前缀和后缀分别排序,那么每个字符串都有前缀的名次x和后缀的名次y
把每个字符串想象成一个点(x,y)
那么询问时的前缀就一定是一个连续的区间[l,r]
同理,后缀也是连续的区间[a,b]
这里的a,b,l,r都可以用二分求出,也可以都加入到原序列中一起排序得出
那么变成求在这两个区间的交集中有多少个点

离线处理
对于询问,拆成两个即x为1~l区间和1~r区间,用后者-前者
从小到大排序,然后对于某个询问的z可能属于原来询问的后者或前者,判断一下就好
用树状数组维护此时(x=1-z)时y的个数,询问时调用就行了
c++排序建议用sort,二分因为我不会用upperbound之类的所以打了四个,判断大小也打了四个……

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 101000
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,q,ans[N],e[N*2],bz[N];
struct note{char a[110];int n,z;
}s[N],t[N];struct node{int x,y,z,r;
}c[N],b[N];bool cnt(node x,node y){return x.x<y.x;}
bool cmt(note x,note y)
{fo(i,1,min(x.n,y.n)){if(x.a[i]<y.a[i]) return 1;if(x.a[i]>y.a[i]) return 0;}if(x.n<y.n) return 1;else return 0;
}
bool cmt2(note x,note y)
{fo(i,1,min(x.n,y.n)){if(x.a[x.n-i+1]<y.a[y.n-i+1]) return 1;if(x.a[x.n-i+1]>y.a[y.n-i+1]) return 0;}if(x.n<y.n) return 1;else return 0;
}
bool same(note x,note y)
{fo(i,1,y.n)if(x.a[i]!=y.a[i]) return 0;return 1;
}
bool same1(note x,note y)
{fo(i,1,y.n)if(x.a[x.n-i+1]!=y.a[y.n-i+1]) return 0;return 1;
}
bool cnt1(note x,note y)
{fo(i,1,x.n) {if(x.a[i]<y.a[i]) return 1;if(x.a[i]>y.a[i]) return 0;}return 1;
}
bool cnt2(note x,note y)
{fo(i,1,x.n) {if(x.a[i]>y.a[i]) return 1;if(x.a[i]<y.a[i]) return 0;}return 1;
}
bool cnt3(note x,note y)
{fo(i,1,x.n) {if(x.a[x.n-i+1]<y.a[y.n-i+1]) return 1;if(x.a[x.n-i+1]>y.a[y.n-i+1]) return 0;}return 1;
}
bool cnt4(note x,note y)
{fo(i,1,x.n) {if(x.a[x.n-i+1]>y.a[y.n-i+1]) return 1;if(x.a[x.n-i+1]<y.a[y.n-i+1]) return 0;}return 1;
}
int ef1(int l,int r,note z)
{while(l+1<r){int m=(l+r)/2;if(cnt1(z,s[m])) r=m;else l=m;}if(same(s[l],z)) r=l;return r;
}
int ef2(int l,int r,note z)
{while(l+1<r){int m=(l+r)/2;if(cnt3(z,t[m])) r=m;else l=m;}if(same1(t[l],z)) r=l;return r;
}
int ef3(int l,int r,note z)
{while(l+1<r){int m=(l+r)/2;if(cnt4(z,t[m])) l=m;else r=m;}if(same1(t[r],z)) l=r;return l;
}
int ef4(int l,int r,note z)
{while(l+1<r){int m=(l+r)/2;if(cnt2(z,s[m])) l=m;else r=m;}if(same(s[r],z)) l=r;return l;
}
int lowbit(int x){return x&(-x);}
void insert(int x)
{for(;x<=n;x+=lowbit(x)) e[x]++;
}
int get(int x)
{int an=0;for(;x;x-=lowbit(x)) an+=e[x];return an;
}
int main()
{scanf("%d%d\n",&n,&q);fo(i,1,n) scanf("%s\n",s[i].a+1),s[i].n=strlen(s[i].a+1),s[i].z=i,t[i]=s[i];sort(s+1,s+n+1,cmt);fo(i,1,n) c[s[i].z].x=i;sort(t+1,t+n+1,cmt2);fo(i,1,n) c[t[i].z].y=i;int tot=0;fo(i,1,q){note x,y;scanf("%s\n",x.a+1);scanf("%s\n",y.a+1);x.n=strlen(x.a+1),y.n=strlen(y.a+1);int jy1=ef2(1,n,y);int jy2=ef3(1,n,y);b[++tot].x=ef1(1,n,x);b[tot].y=jy1;b[tot].r=jy2;b[tot].z=i;b[++tot].x=ef4(1,n,x)+1;b[tot].y=jy1;b[tot].r=jy2;b[tot].z=i;}sort(c+1,c+n+1,cnt);sort(b+1,b+tot+1,cnt);int j=1;fo(i,1,tot){for(;c[j].x<b[i].x&&j<=n;j++) insert(c[j].y);int jy=get(b[i].r);jy -=get(b[i].y-1);if(bz[b[i].z]==0) ans[b[i].z]-=jy,bz[b[i].z]=1;else ans[b[i].z]+=jy;}fo(i,1,q) printf("%d\n",ans[i]);
}

这篇关于【长郡NOIP2014模拟10.22】字符串查询的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1012471

相关文章

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Python 常用数据类型详解之字符串、列表、字典操作方法

《Python常用数据类型详解之字符串、列表、字典操作方法》在Python中,字符串、列表和字典是最常用的数据类型,它们在数据处理、程序设计和算法实现中扮演着重要角色,接下来通过本文给大家介绍这三种... 目录一、字符串(String)(一)创建字符串(二)字符串操作1. 字符串连接2. 字符串重复3. 字

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

Java 字符串操作之contains 和 substring 方法最佳实践与常见问题

《Java字符串操作之contains和substring方法最佳实践与常见问题》本文给大家详细介绍Java字符串操作之contains和substring方法最佳实践与常见问题,本文结合实例... 目录一、contains 方法详解1. 方法定义与语法2. 底层实现原理3. 使用示例4. 注意事项二、su

Java 单元测试之Mockito 模拟静态方法与私有方法最佳实践

《Java单元测试之Mockito模拟静态方法与私有方法最佳实践》本文将深入探讨如何使用Mockito来模拟静态方法和私有方法,结合大量实战代码示例,带你突破传统单元测试的边界,写出更彻底、更独立... 目录Mockito 简介:为什么选择它?环境准备模拟静态方法:打破“不可变”的枷锁传统困境解法一:使用M

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

MySQL之复合查询使用及说明

《MySQL之复合查询使用及说明》文章讲解了SQL复合查询中emp、dept、salgrade三张表的使用,涵盖多表连接、自连接、子查询(单行/多行/多列)及合并查询(UNION/UNIONALL)等... 目录复合查询基本查询回顾多表查询笛卡尔积自连接子查询单行子查询多行子查询多列子查询在from子句中使

Vue3 如何通过json配置生成查询表单

《Vue3如何通过json配置生成查询表单》本文给大家介绍Vue3如何通过json配置生成查询表单,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录功能实现背景项目代码案例功能实现背景通过vue3实现后台管理项目一定含有表格功能,通常离不开表单

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H