ACM
Time Limit: 2 Sec
Memory Limit: 128 MB
Submissions: 166 Solved: 16
Description
Jianhe25 is a ACMer, he loves "ACM" very much, so he wants to know how many times "ACM" appear in the string.
Jianhe25 thinks it's so naive, so he wants to make it more difficult. He defines two types of operation:
C i x
It means to change the ith character into x , and x is a character which will always be capital letters 'A', 'C' or 'M'.
Q i j ( 1 <=i <= j<=n )
It means to count the times the substring "ACM" appear within the range of [i,j] of the string and print it on the screen.
Jianhe25 thinks it's so naive, so he wants to make it more difficult. He defines two types of operation:
C i x
It means to change the ith character into x , and x is a character which will always be capital letters 'A', 'C' or 'M'.
Q i j ( 1 <=i <= j<=n )
It means to count the times the substring "ACM" appear within the range of [i,j] of the string and print it on the screen.
Input
The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has two integers n m , 1 <= n,m <= 10000 , that represents the length of the string and the number of operations, and the second line contains n character which always be the Capital letters 'A','
C'or'M'. Followed by m lines, each line represents the operation.
Output
The output should contain the times "ACM" appear in the string, one per line.
Sample Input
1 6 8 ACACMM Q 1 6 Q 1 2 C 3 M C 4 A C 5 C C 6 M Q 1 6 Q 2 4
Sample Output
1 0 2 0
HINT
Huge Input/Output , scanf/
printf is recommended.
Source
The 6th ACM Programming Contest of HUST
题目比较简单,直接比对,结果用树状数组维护
#include <string.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn = 15000;
int n,m;
char str[maxn];
int tree[maxn];
bool rec[maxn];
int lowbit(int x){
return x&(-x);
}
int update(int x,int num){
while(x<=n){
tree[x]+=num;
x+=lowbit(x);
}
return 0;
}
int sum(int pos){
int sum=0;
while(pos>0){
sum+=tree[pos];
pos-=lowbit(pos);
}
return sum;
}
int main(){
int i,j,k,t,a,b;
char s[10];
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(tree,0,sizeof(tree));
memset(rec,false,sizeof(rec));
scanf("%s",str+1);
for(i=3;i<=n;i++){
if(str[i]=='M' && str[i-1]=='C' && str[i-2]=='A'){
update(i,1);
rec[i]=1;
}
}
for(i=0;i<m;i++){
scanf("%s",s);
if(s[0]=='Q'){
scanf("%d%d",&a,&b);
if(a+2>b){
printf("0\n");
}else{
printf("%d\n",sum(b)-sum(a+2)+rec[a+2]);
}
}else{
scanf("%d%s",&a,s);
if(s[0]==str[a]) continue;
str[a]=s[0];
if(a>=3){
if(rec[a]){
update(a,-1);
rec[a]=false;
}else{
if(str[a]=='M' && str[a-1]=='C' && str[a-2]=='A'){
update(a,1);
rec[a]=true;
}
}
if(rec[a+1]){
update(a+1,-1);
rec[a+1]=false;
}else{
if(str[a+1]=='M' && str[a-1+1]=='C' && str[a-2+1]=='A'){
update(a+1,1);
rec[a+1]=true;
}
}
if(rec[a+2]){
update(a+2,-1);
rec[a+2]=false;
}else{
if(str[a+2]=='M' && str[a-1+2]=='C' && str[a-2+2]=='A'){
update(a+2,1);
rec[a+2]=true;
}
}
}
if(a==2){
if(rec[a+1]){
update(a+1,-1);
rec[a+1]=false;
}else{
if(str[a+1]=='M' && str[a-1+1]=='C' && str[a-2+1]=='A'){
update(a+1,1);
rec[a+1]=true;
}
}
if(rec[a+2]){
update(a+2,-1);
rec[a+2]=false;
}else{
if(str[a+2]=='M' && str[a-1+2]=='C' && str[a-2+2]=='A'){
update(a+2,1);
rec[a+2]=true;
}
}
}
if(a==1){
if(rec[a+2]){
update(a+2,-1);
rec[a+2]=false;
}else{
if(str[a+2]=='M' && str[a-1+2]=='C' && str[a-2+2]=='A'){
update(a+2,1);
rec[a+2]=true;
}
}
}
}
}
}
return 0;
}
本文探讨了在ACM比赛中遇到的字符串匹配问题,通过操作改变字符串中的字符并计算特定子串出现次数的方法。利用树状数组实现高效查询和更新,适合处理大量数据输入,提供了解题思路和代码实现。
334

被折叠的 条评论
为什么被折叠?



