您的位置:首页 > 理论基础 > 计算机网络

2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 Query on a string(字符串+树状数组)

2017-09-18 14:10 603 查看
啊啊啊,字符串几乎完全不懂啊.

迷迷糊糊的看了下kmp,感觉也和纯套模版没区别了..

这题一看到就觉得是线段树什么的,但是并没有想到只是通过数据结构来方便求和(好菜啊好菜啊好菜啊).

幻想一些直接query,把字符串分开再组合就能得到答案的方法..

用kmp先整体处理,在每一个小修改时,复杂度是很低的.

复杂度约等于nlogn

/*  xzppp  */
#include <iostream>
#include <vector>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <list>
#include <string>
#include <cmath>
#include <bitset>
#include <iomanip>
using namespace std;
#define FFF freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MP make_pair
#define PB push_back
#define _ %MOD
typedef long long  LL;
typedef unsigned long long ULL;
typedef pair<int,int > pii;
typedef pair<LL,LL> pll;
typedef pair<double,double > pdd;
typedef pair<double,int > pdi;
const int MAXN = 1e5+17;
const int MAXM = 1e6+17;
const int MAXV = 2*1e3+17;
const int BIT = 15+3;
const int INF = 0x7f7f7fff;
const LL INFF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9+7;
int Next[MAXN],uset[MAXN];
string targ,pat;
int bit[MAXN];
void add(int p,int x)
{
int n = targ.size();
while(p<=n)
{
bit[p]+=x;
p += p&-p;
}
}
int sum(int p)
{
int n = targ.size();
int res = 0;
while(p>0)
{
res += bit[p];
p -= p&-p;
}
return res;
}
void init(string pat)
{
int lp = pat.length();
for (int i=1;i<lp;i++)
{
int j=Next[i];
while(j && pat[i]!=pat[j])
j=Next[j];
Next[i+1]=(pat[i]==pat[j])?j+1:0;
}
}
void kmp(string targ,string pat)
{
init(pat);
int lt = targ.length(),lp = pat.length();
for (int i=0,j = 0;i<lt;i++)
{
while (j&&targ[i]!=pat[j]) j=Next[j];
if (targ[i]==pat[j]) j++;
if (j==lp)
{
add(i+1,1);
uset[i+1] = 1;
//cout<<i+1<<endl;
j = Next[j];
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
FFF
#endif
int t;
cin>>t;
while(t--)
{
memset(bit, 0, sizeof(bit));
memset(uset, 0, sizeof(uset));
memset(Next, 0, sizeof(Next));
int n;
cin>>n;
cin>>targ>>pat;
kmp(targ,pat);
for (int i = 0; i < n; ++i)
{
char cmd[5];
scanf("%s",cmd);
if(cmd[0]=='Q')
{
//cout<<targ<<endl;
int s,t;
scanf("%d%d",&s,&t);
//cout<<t<<"  "<<s+pat.size()-2<<endl;
printf("%d\n", sum(t)-sum(s+pat.size()-2));
}
else
{
int p;
char cg[5];
scanf("%d%s",&p,cg);
targ[p-1] = cg[0];
//cout<<targ<<endl;
int s = max(1,p-(int)pat.size()+1);
for (int i = s; i <= p ; ++i)
{
bool can = true;
for (int j = 1; j <= pat.size(); ++j)
{
if(targ[i+j-2]!=pat[j-1])
{
can = false;
break;
}
}
int cgp = i+pat.size()-1;
if(!can&&uset[cgp]==1)
{
add(cgp,-1);
uset[cgp] = 0;
}
if(can&&uset[cgp]!=1)
{
uset[cgp] = 1;
add(cgp,1);
}
}
}
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm-icpc string kmp
相关文章推荐