zoukankan      html  css  js  c++  java
  • 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
    ",ans);
             }
        }
        return 0;
    }
  • 相关阅读:
    让.Net程序支持命令行启动
    拒绝卡顿——在WPF中使用多线程更新UI
    比NPOI更好用的Excel操作库——EPPlus
    利用Visual Studio Natvis 框架简化C++的变量调试工作
    使用LibZ合并.Net程序集,支持WPF
    SONY新的圈铁耳机
    找回VisualStudio异常设置中丢失的“用户未处理的(User-unhandled)”列
    去除下载文件属性中烦人的锁定状态
    POJ 3347 Kadj Squares
    POJ 1696 Space Ant(极角排序)
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5086720.html
Copyright © 2011-2022 走看看