计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛G题Query on a strin(树状数组+暴力更新)
2017-09-11 15:50
513 查看
题意:
给一个<=1e5的主串,一个<=10的匹配串,n次询问或操作,询问主串的[l, r]区间内与匹配串能匹配的个数(可重叠),操作给定一个位置pos和字符ch,将s[pos]改为ch。
思路:
由于匹配串长度很小,完全可以暴力去做,主串中与匹配串匹配的子串只有起点位置有值,然后通过树状数组维护区间和即可,不过查询时要注意一个小判断,区间有可能不足匹配串的长度。更新时,暴力去更新,改变一个字符,只会影响其前面少于十个位置,其后面少于十个位置。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
char s[maxn], p[15], mk1, mk2;
int a[maxn], tree[maxn];
int t, n, len1, len2, x, y;
int lowbit(int x){return x&(-x);}
void update(int k, int val)
{
while(k <= len1)
{
tree[k] += val;
k += lowbit(k);
}
}
int query(int k)
{
int ans = 0;
while(k)
{
ans += tree[k];
k -= lowbit(k);
}
return ans;
}
void init()
{
len1 = strlen(s+1);
len2 = strlen(p+1);
memset(tree, 0, sizeof tree);
for(int i = 1; i+len2-1 <= len1; ++i)
{
int t = 1;
while(t <= len2 && s[i+t-1] == p[t]) ++t;
a[i] = (t > len2);
update(i, a[i]);
}
}
int main()
{
//freopen("in.txt", "r", stdin);
for(scanf("%d", &t); t--;)
{
scanf("%d", &n);
scanf("%s", s+1);
scanf("%s", p+1);
init();
while(n--)
{
scanf(" %c %d", &mk1, &x);
if(mk1 == 'C')
{
scanf(" %c", &mk2);
if(s[x] == mk2) continue;
s[x] = mk2;
int st = x-len2+1, ed = x+len2-1;
if(st < 1) st = 1;
if(ed > len1) ed = len1;
for(int i = st; i <= ed && i+len2-1 <= len1; ++i)
{
int t = 1;
while(t <= len2 && s[i+t-1] == p[t]) ++t;
int chg = (t > len2);
if(a[i]) a[i] = 0, update(i, -1);
if(chg) a[i] = 1, update(i, 1);
}
}
else
{
scanf("%d", &y);
int ans = 0;
if(y-len2+1 >= x)
printf("%d\n", query(y-len2+1)-query(x-1));
else puts("0");
}
}
puts("");
}
return 0;
}
继续加油~
给一个<=1e5的主串,一个<=10的匹配串,n次询问或操作,询问主串的[l, r]区间内与匹配串能匹配的个数(可重叠),操作给定一个位置pos和字符ch,将s[pos]改为ch。
思路:
由于匹配串长度很小,完全可以暴力去做,主串中与匹配串匹配的子串只有起点位置有值,然后通过树状数组维护区间和即可,不过查询时要注意一个小判断,区间有可能不足匹配串的长度。更新时,暴力去更新,改变一个字符,只会影响其前面少于十个位置,其后面少于十个位置。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
char s[maxn], p[15], mk1, mk2;
int a[maxn], tree[maxn];
int t, n, len1, len2, x, y;
int lowbit(int x){return x&(-x);}
void update(int k, int val)
{
while(k <= len1)
{
tree[k] += val;
k += lowbit(k);
}
}
int query(int k)
{
int ans = 0;
while(k)
{
ans += tree[k];
k -= lowbit(k);
}
return ans;
}
void init()
{
len1 = strlen(s+1);
len2 = strlen(p+1);
memset(tree, 0, sizeof tree);
for(int i = 1; i+len2-1 <= len1; ++i)
{
int t = 1;
while(t <= len2 && s[i+t-1] == p[t]) ++t;
a[i] = (t > len2);
update(i, a[i]);
}
}
int main()
{
//freopen("in.txt", "r", stdin);
for(scanf("%d", &t); t--;)
{
scanf("%d", &n);
scanf("%s", s+1);
scanf("%s", p+1);
init();
while(n--)
{
scanf(" %c %d", &mk1, &x);
if(mk1 == 'C')
{
scanf(" %c", &mk2);
if(s[x] == mk2) continue;
s[x] = mk2;
int st = x-len2+1, ed = x+len2-1;
if(st < 1) st = 1;
if(ed > len1) ed = len1;
for(int i = st; i <= ed && i+len2-1 <= len1; ++i)
{
int t = 1;
while(t <= len2 && s[i+t-1] == p[t]) ++t;
int chg = (t > len2);
if(a[i]) a[i] = 0, update(i, -1);
if(chg) a[i] = 1, update(i, 1);
}
}
else
{
scanf("%d", &y);
int ans = 0;
if(y-len2+1 >= x)
printf("%d\n", query(y-len2+1)-query(x-1));
else puts("0");
}
}
puts("");
}
return 0;
}
继续加油~
相关文章推荐
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛H题Skiing(拓扑序求DAG最长路)
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛J题Our Journey of Dalian Ends (最小费用最大流)
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-A-Banana
- 计蒜客 16952 Coconut(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 C)
- 计蒜客 16954 Half-consecutive Numbers(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 E)
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-C-Coconut
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛F题Islands(有向图加最少的边变成强连通图)
- 计蒜客 16955 Islands(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 F)
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-E-Half-consecutive Numbers
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-F-Islands
- 计蒜客:2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛:Our Journey of Dalian Ends
- 计蒜客 16956 Query on a string(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G)
- 2017 ACM-ICPC乌鲁木齐网络赛 G. Query on a string 【KMP+树状数组】
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-G-Query on a string
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 Query on a string(字符串+树状数组)
- 计蒜客 16957 Skiing(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 H)
- [计蒜客16955] Islands [2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 F]
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-J-Our Journey of Dalian Ends
- 重要-- 模板 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛J题Our Journey of Dalian Ends (最小费用最大流)
- 计蒜客 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B coin(求乘法逆元)