1 条题解
-
0
自动搬运
来自洛谷,原作者为

SunsetVoice
**搬运于
2025-08-24 23:07:07,当前版本为作者最后更新于2024-12-18 18:32:22,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
提供一个能将此题降上位橙的解法。
先按 从小到大排序对每一个可能的前缀建桶,记录所有能对这个字符串产生贡献的 数值,最后对 做前缀和。
由于我们已经按 排好了序,所以 在数组中一定是从小到大排序的,查询时二分即可。
复杂度(使用
map情况下) 。考虑在常数上优化,首先尽量少开
long long,后对每个桶记录是否已计算好前缀和以保证计算时只计算一次,再优化输入输出即可。#include<bits/stdc++.h> using namespace std; struct memory{ bool isvb; vector<long long>d,v,vb; void cl(){ long long sum = 0; for(long long hjx:v){ sum+=hjx; vb.push_back(sum); } isvb = 1; } }; map<string,memory>mp; long long n,m; struct node{ int d,v; string str; }a[200001]; bool cmp(node x,node y){ return x.d<y.d; } inline string read() { string str=""; char ch=getchar(); while(ch==' ' || ch=='\n' || ch=='\r') { ch=getchar(); } while(ch!=' ' && ch!='\n' && ch!='\r') { str+=ch; ch=getchar(); } return str; } signed main(){ scanf("%lld %lld",&n,&m); for(register int i = 1;i<=n;i++){ scanf("%d %d",&a[i].d,&a[i].v); a[i].str = read(); } sort(a+1,a+1+n,cmp); for(register int i = 1;i<=n;i++){ string nstr = ""; int gl = a[i].str.length(); for(register int j = 0;j<gl;j++){ nstr+=a[i].str[j]; mp[nstr].d.push_back(a[i].d); mp[nstr].v.push_back(a[i].v); mp[nstr].isvb = 0; } } for(int i = 1;i<=n;i++){ string nstr = ""; int gl = a[i].str.length(); for(int j = 0;j<gl;j++){ nstr+=a[i].str[j]; if(mp[nstr].isvb==0){ mp[nstr].cl(); } } } while(m--){ int fd; string fq; scanf("%d",&fd); cin>>fq; if(!mp.count(fq)){ printf("0\n"); continue; } int pos = upper_bound(mp[fq].d.begin(),mp[fq].d.end(),fd)-mp[fq].d.begin()-1; if(pos<0){ printf("0\n"); continue; } printf("%lld\n",mp[fq].vb[pos]); } return 0; }
- 1
信息
- ID
- 10770
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者