zoukankan      html  css  js  c++  java
  • CF610E Alphabet Permutations

    题面
    英文题面
    题意:给定一个长度为(n)的字符串(s),有(m)次操作:
    1.将区间([L,R])内的字符变为(ch)
    2.给定长度为(k)的字符串排列(t),向(s)中添加字符,使得(s)(t)为模式循环,求最少的循环次数。
    (n leq 2 imes 10^5 ,m leq 2 imes 10^4, 1 leq k leq 10)
    题解:
    考虑两个相邻字符(i)(i+1),它们对答案会产生1的贡献当且仅当:(p_{c_i} geq p_{c_{i+1}})
    这样的话,我们单次查询只需要统计每个字符之间的贡献即可。
    用线段树维护这个东西就好了。
    时间复杂度:(O(nlogn imes k^2))
    代码:

    #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
    ",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;
    }
    
  • 相关阅读:
    WPF入门教程系列十二——依赖属性(二)
    WPF入门教程系列十一——依赖属性(一)
    WPF入门教程系列十——布局之Border与ViewBox(五)
    WPF入门教程系列九——布局之DockPanel与ViewBox(四)
    WPF入门教程系列八——布局之Grid与UniformGrid(三)
    WPF入门教程系列七——布局之WrapPanel与StackPanel(二)
    WPF入门教程系列六——布局介绍与Canvas(一)
    WPF入门教程系列五——Window 介绍
    WPF入门教程系列四——Dispatcher介绍
    WPF入门教程系列三——Application介绍(续)
  • 原文地址:https://www.cnblogs.com/Purple-wzy/p/13263816.html
Copyright © 2011-2022 走看看