Query on a string(线段树)(2017-icpc-乌鲁木齐网络赛)
2017-09-09 16:51
453 查看
You have two strings SSS
and TTT
in all capitals.
Now an efficient program is required to maintain a operation and support a query.
The operation C i chC~i~chC i ch
with given integer iii
and capital letter chchch,
changes the iii-th
character of SSS
into chchch.
The query Q i jQ~i~jQ i j
asks the program to find out, in the substring of SSS
from the iii-th
character to the jjj-th
one, the total number of TTT
appearing.
Input Format
The first line contains an integer TTT,indicating that there are TTT
test cases.
For each test case, the first line contains an integer N (N≤100000)N~(N \leq 100000)N (N≤100000).
The second line is the string S (∣S∣≤100000)S~(|S| \leq 100000)S (∣S∣≤100000)
and the third line is the string T (∣T∣≤10)T~(|T| \leq 10)T (∣T∣≤10).
Each of the following NNN
lines provide a operation or a query as above descriptions.
Output Format
For each query, output an integer correponding to the answer.Output an empty line after each test case.
样例输入
1 5 AABBABA AA Q 1 3 C 6 A Q 2 7 C 2 B Q 1 5
样例输出
1 2 0
题意:t组测试数据,n次操作,给两个字符串S,T;,Q X Y表示查询在S串中第X--Y这段字符串内T串出现了几次;C X ch 将S串中第X个字符改成ch
思路:将第一个串处理一下,如果以当前字符为第一个字符,若出现了第二个字符串,用另一个数组将当前点记录为1,否则为0;如样例AABBABA AA,记录的数组为1000000,然后以这个记录数组建线段树,查询就是求这个区间的和,更改就是线段树单点更新,但是要注意S字符串最后几个到最后长度都比T字符串小就不用判断了;具体看代码:
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
#define maxn 100005
using namespace std;
char str[maxn],s[maxn];
int arr[maxn],len,ll;
void Getarr(char *str,char *s)
{
for(int i=0;i<len;i++)
{
int flag=1;
for(int j=0;j<ll;j++)
{
if(str[i+j]!=s[j]||i+ll>len)//如果i+ll>len,说明到最后都不能构成T
{
flag=0;
arr[i]=0;
break;
}
}
if(flag)
arr[i]=1;
}
}
struct node
{
int l;
int r;
int sum;
}segtree[maxn*4];
void pushup(int root)
{
segtree[root].sum=segtree[root<<1].sum+segtree[root<<1|1].sum;
}
void build(int root,int l,int r)
{
segtree[root].l=l;
segtree[root].r=r;
if(l==r)
{
segtree[root].sum=arr[l];
return;
}
int mid=(l+r)>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
pushup(root);
}
void update(int root,int p,int val)
{
int ll=segtree[root].l;
int rr=segtree[root].r;
if(ll==rr)
{
segtree[root].sum=val;
return;
}
int mid=(ll+rr)>>1;
if(p<=mid) update(root<<1,p,val);
else update(root<<1|1,p,val);
pushup(root);
}
int query(int root,int l,int r)
{
int ll=segtree[root].l;
int rr=segtree[root].r;
if(l<=ll&&rr<=r)
return segtree[root].sum;
int mid=(ll+rr)>>1;
int ans=0;
if(l<=mid)
ans+=query(root<<1,l,r);
if(r>mid)
ans+=query(root<<1|1,l,r);
return ans;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d%s%s",&n,str,s);
len=strlen(str);ll=strlen(s);
Getarr(str,s);
build(1,0,len-1);
while(n--)
{
char op[5],ch[3];
int x,y;
scanf("%s",op);
if(op[0]=='Q')
{
scanf("%d%d",&x,&y);
if(y-x+1<ll){//查询求见长度比T字符串长度小,直接输出0
printf("0\n");
continue;
}
x--;y--;
printf("%d\n",query(1,x,y-ll+1));//查询的右端点要减去T字符串的长度+1,想想为什么
}
else
{
scanf("%d%s",&x,ch);
x--;
str[x]=ch[0];
int tmp=x-ll+1>=0?x-ll+1:0;
for(int i=tmp;i<=x;i++)
{
int flag=1;
for(int j=0;j<ll;j++)
{
if(str[i+j]!=s[j]||i+ll>len)
{
if(arr[i]!=0)
update(1,i,0);
arr[i]=0;
flag=0;
break;
}
}
if(flag==1)
{
if(arr[i]!=1)
update(1,i,1);
arr[i]=1;
}
}
}
}
cout<<endl;
}
return 0;
}
相关文章推荐
- 2017 ACM-ICPC乌鲁木齐网络赛 G. Query on a string(KMP+树状数组)
- 2017 ACM-ICPC乌鲁木齐网络赛 G. Query on a string 【KMP+树状数组】
- 【2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G】Query on a string
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 - G Query on a string (KMP+树状数组)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 Query on a string(字符串+树状数组)
- 计蒜客 16956 Query on a string(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G)
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-G-Query on a string
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛(G. Query on a string)kmp+线段树
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G题 Query on a string
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-G: Query on a string(线段树+预处理)
- [计蒜客16956] Query on a string [2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G]
- 计蒜客 16952 Coconut(2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 C)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-A. Banana
- H. Skiing 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛
- 【2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 】H Skiing 【求DAG图的最长路】
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 E. Half-consecutive Numbers
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 E. Half-consecutive Numbers
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 A. Banana(连通性水题)
- F. Islands 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-E-Half-consecutive Numbers