2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 Query on a string(字符串+树状数组)
2017-09-18 14:10
603 查看
啊啊啊,字符串几乎完全不懂啊.
迷迷糊糊的看了下kmp,感觉也和纯套模版没区别了..
这题一看到就觉得是线段树什么的,但是并没有想到只是通过数据结构来方便求和(好菜啊好菜啊好菜啊).
幻想一些直接query,把字符串分开再组合就能得到答案的方法..
用kmp先整体处理,在每一个小修改时,复杂度是很低的.
复杂度约等于nlogn
迷迷糊糊的看了下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; }
相关文章推荐
- 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)
- 【2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 G】Query on a string
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛(G. Query on a string)kmp+线段树
- [计蒜客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(KMP+树状数组)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 E.Half-consecutive Numbers
- Query on a string(线段树)(2017-icpc-乌鲁木齐网络赛)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛-H Skiing
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛G题Query on a strin(树状数组+暴力更新)
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛H题Skiing(拓扑序求DAG最长路)
- 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛J题Our Journey of Dalian Ends (最小费用最大流)
- [计蒜客16955] Islands [2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 F]
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区) 网络赛 H.Skiing(求有向无环图的最长路)
- 重要-- 模板 计蒜客-2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛J题Our Journey of Dalian Ends (最小费用最大流)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 F.islands (强联通分量 + 缩点)