CF 610E. Alphabet Permutations
题目:http://codeforces.com/problemset/problem/610/E
如果存在c1,c2在原串相邻且在询问串中c1在c2前面的话,把它们在原串出现次数加起来记作sum,那么n-sum就是答案。
维护一棵线段树,线段树的每个节点存一个k^2的矩阵。
然后修改的话就在线段树上区间修改。。(标记下传的时候要注意不要越界TAT。。。
然后询问的话就k^2搞一下需要被减掉的字符对就好了。。
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define low(x) (x&(-x)) #define maxn 12 #define ll long long using namespace std; int n,m,K,ans; char s[200500],s2[maxn]; int a[maxn][maxn]; struct data{int mat[maxn][maxn],l,r,tag; }t[200500*4]; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)){x=x*10+ch-'0'; ch=getchar();} return x*f; } void combine(data &a,data b,data c){ a.l=b.l; a.r=c.r; rep(i,0,K-1) rep(j,0,K-1) a.mat[i][j]=b.mat[i][j]+c.mat[i][j]; a.mat[b.r][c.l]++; a.tag=-1; } void build(int i,int l,int r){ int mid=(l+r)/2; if (l==r){ t[i].tag=-1; t[i].l=t[i].r=s[l]-'a'; clr(t[i].mat,0); return ; } build(i*2,l,mid); build(i*2+1,mid+1,r); combine(t[i],t[i*2],t[i*2+1]); } void ps(int i,int l,int r){ if (t[i].tag!=-1){ t[i].l=t[i].r=t[i].tag; clr(t[i].mat,0); t[i].mat[t[i].tag][t[i].tag]=r-l; if (l!=r) t[i*2].tag=t[i*2+1].tag=t[i].tag; t[i].tag=-1; } } void change(int i,int l,int r,int tl,int tr,int val){ ps(i,l,r); int mid=(l+r)/2; if (l==tl&&r==tr){ t[i].tag=val; ps(i,l,r); return ; } if (tr<=mid) { change(i*2,l,mid,tl,tr,val); ps(i*2+1,mid+1,r); } else if (tl>mid){ change(i*2+1,mid+1,r,tl,tr,val); ps(i*2,l,mid); } else { change(i*2,l,mid,tl,mid,val); change(i*2+1,mid+1,r,mid+1,tr,val); } combine(t[i],t[i*2],t[i*2+1]); } int main(){ n=read(); m=read(); K=read(); scanf("%s",s); build(1,0,n-1); rep(i,1,m){ int op=read(); if (op==1){ int l=read()-1,r=read()-1; scanf("%s",s2); int now=s2[0]-'a'; change(1,0,n-1,l,r,now); } else { ans=n; scanf("%s",s2); rep(j,0,K-1) rep(k,0,K-1) a[j][k]=0; rep(j,0,K-1) rep(k,j+1,K-1) a[s2[j]-'a'][s2[k]-'a']=1; rep(j,0,K-1) rep(k,0,K-1) ans-=t[1].mat[j][k]*a[j][k]; printf("%d\n",ans); } } return 0; }