題面
英文題面
題意:給定一個長度爲\(n\)的字符串\(s\),有\(m\)次操做:
1.將區間\([L,R]\)內的字符變爲\(ch\)
2.給定長度爲\(k\)的字符串排列\(t\),向\(s\)中添加字符,使得\(s\)以\(t\)爲模式循環,求最少的循環次數。
\(n \leq 2\times 10^5 ,m \leq 2\times 10^4, 1 \leq k \leq 10\)。
題解:
考慮兩個相鄰字符\(i\)和\(i+1\),它們對答案會產生1的貢獻當且僅當:\(p_{c_i} \geq p_{c_{i+1}}\)
這樣的話,咱們單次查詢只須要統計每一個字符之間的貢獻便可。
用線段樹維護這個東西就行了。
時間複雜度:\(O(nlogn \times k^2)\)
代碼:c++
#include<bits/stdc++.h> using namespace std; #define re register int #define F(x,y,z) for(re x=y;x<=z;x++) #define FOR(x,y,z) for(re x=y;x>=z;x--) typedef long long ll; #define I inline void #define IN inline int #define C(x,y) memset(x,y,sizeof(x)) #define STS system("pause") template<class D>I read(D &res){ res=0;register D g=1;register char ch=getchar(); while(!isdigit(ch)){ if(ch=='-')g=-1; ch=getchar(); } while(isdigit(ch)){ res=(res<<3)+(res<<1)+(ch^48); ch=getchar(); } res*=g; } char c[202000]; int tr[808000][10][10],len[808000],laz[808000],lft[808000],rit[808000]; int n,m,s,ans,sit,L,R,W; #define all 1,1,n #define lt k<<1,l,mid #define rt k<<1|1,mid+1,r I add(int k,int w){ lft[k]=rit[k]=laz[k]=w; F(i,0,9)F(j,0,9)tr[k][i][j]=0; tr[k][w][w]=len[k]-1; } I push_down(int k){ add(k<<1,laz[k]);add(k<<1|1,laz[k]);laz[k]=-1; } I build(int k,int l,int r){ laz[k]=-1; if(l==r)return len[k]=1,lft[k]=rit[k]=c[l]-'a',void(); re mid=(l+r)>>1; build(lt);build(rt); F(i,0,9)F(j,0,9)tr[k][i][j]=tr[k<<1][i][j]+tr[k<<1|1][i][j]; tr[k][rit[k<<1]][lft[k<<1|1]]++; lft[k]=lft[k<<1];rit[k]=rit[k<<1|1]; len[k]=len[k<<1]+len[k<<1|1]; } I modi(int k,int l,int r,int x,int y,int w){ if(x>r||y<l)return; if(x<=l&&r<=y)return add(k,w),void(); if(laz[k]!=-1)push_down(k); re mid=(l+r)>>1; modi(lt,x,y,w);modi(rt,x,y,w); F(i,0,9)F(j,0,9)tr[k][i][j]=tr[k<<1][i][j]+tr[k<<1|1][i][j]; tr[k][rit[k<<1]][lft[k<<1|1]]++; lft[k]=lft[k<<1];rit[k]=rit[k<<1|1]; } char t[20],v;int b[20]; I calc(){ ans=n; scanf("%s",t+1); F(i,1,s)b[i]=t[i]-'a'; F(i,1,s-1)F(j,i+1,s)ans-=tr[1][b[i]][b[j]]; printf("%d\n",ans); } int main(){ read(n);read(m);read(s); scanf("%s",c+1);build(all); while(m--){ read(sit); if(sit==1){ read(L);read(R);scanf("%c",&v);W=v-'a'; modi(all,L,R,W); } else calc(); } return 0; }