zoukankan      html  css  js  c++  java
  • codeforces 954I (标算FFT,bitset水过)

    这题题意非常之裸。定义一种变换是模糊两个字符,求s的每个与t长度相等的子串变成与t相等的的最小变换次数。

    一眼就看出这是FFT,但是不会构造。

    于是就看了一眼数据范围,125000,bitset可以水。(虽然好想好写,但是罚时爆炸,不过小号rating无关紧要)

    思路就是和bitset字符串匹配的思路差不多。

    复杂度O(m*(n-m)/计算机位数)

    简写O(能过)

    codeforces评测机是64位无疑。

    然后大力卡常即可。

    代码:

    #pragma GCC target("avx")
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    #pragma GCC optimize("-fgcse")
    #pragma GCC optimize("-fgcse-lm")
    #pragma GCC optimize("-fipa-sra")
    #pragma GCC optimize("-ftree-pre")
    #pragma GCC optimize("-ftree-vrp")
    #pragma GCC optimize("-fpeephole2")
    #pragma GCC optimize("-ffast-math")
    #pragma GCC optimize("-fsched-spec")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC optimize("-falign-jumps")
    #pragma GCC optimize("-falign-loops")
    #pragma GCC optimize("-falign-labels")
    #pragma GCC optimize("-fdevirtualize")
    #pragma GCC optimize("-fcaller-saves")
    #pragma GCC optimize("-fcrossjumping")
    #pragma GCC optimize("-fthread-jumps")
    #pragma GCC optimize("-funroll-loops")
    #pragma GCC optimize("-fwhole-program")
    #pragma GCC optimize("-freorder-blocks")
    #pragma GCC optimize("-fschedule-insns")
    #pragma GCC optimize("inline-functions")
    #pragma GCC optimize("-ftree-tail-merge")
    #pragma GCC optimize("-fschedule-insns2")
    #pragma GCC optimize("-fstrict-aliasing")
    #pragma GCC optimize("-fstrict-overflow")
    #pragma GCC optimize("-falign-functions")
    #pragma GCC optimize("-fcse-skip-blocks")
    #pragma GCC optimize("-fcse-follow-jumps")
    #pragma GCC optimize("-fsched-interblock")
    #pragma GCC optimize("-fpartial-inlining")
    #pragma GCC optimize("no-stack-protector")
    #pragma GCC optimize("-freorder-functions")
    #pragma GCC optimize("-findirect-inlining")
    #pragma GCC optimize("-fhoist-adjacent-loads")
    #pragma GCC optimize("-frerun-cse-after-loop")
    #pragma GCC optimize("inline-small-functions")
    #pragma GCC optimize("-finline-small-functions")
    #pragma GCC optimize("-ftree-switch-conversion")
    #pragma GCC optimize("-foptimize-sibling-calls")
    #pragma GCC optimize("-fexpensive-optimizations")
    #pragma GCC optimize("-funsafe-loop-optimizations")
    #pragma GCC optimize("inline-functions-called-once")
    #pragma GCC optimize("-fdelete-null-pointer-checks")
    #include<bits/stdc++.h>
    using namespace std;
    const int N1=20010,N2=40010,N3=80010,N4=125010,N5=60010;
    bitset<N1> ss[6],tt[6];
    bitset<N2> sss[6],ttt[6];
    bitset<N3> ssss[6],tttt[6];
    bitset<N4> sssss[6],ttttt[6];
    bitset<N5> ssssss[6],tttttt[6];
    char s[N4],t[N4];
    bool re[6][6],b[6];
    int dfs(int x){
        if (b[x]) return 0;
        b[x]=1;
        int ret=1;
        for (int i=0; i<6; ++i)
        if (re[x][i]||re[i][x]) ret+=dfs(i);
        return ret;
    }
    int main(){
        scanf("%s%s",s,t);
    //    freopen("re.out","w",stdout);
        int n=strlen(s),m=strlen(t);
    //    n=120000,m=60000;
    //    for (int i=0; i<n; ++i) s[i]='a';
    //    for (int i=0; i<m; ++i) t[i]='a';
        if (m<=20000){
            for (int i=0; i<m; ++i) ss[s[i]-'a'].set(i);
            for (int i=0; i<m; ++i) tt[t[i]-'a'].set(i);
            for (int u=0; u<=n-m; ++u){
                int ret=0;
                for (int j=0; j<6; ++j) b[j]=0;
                for (int i=0; i<6; ++i)
                for (int j=0; j<6; ++j){
                    re[i][j]=0;
                    if (j!=i&&(ss[i]&tt[j]).any()) re[i][j]=1;
                }
                for (int i=0; i<6; ++i) if (!b[i]) ret+=dfs(i)-1;
                printf("%d ",ret);
                for (int i=0; i<6; ++i) ss[i]>>=1;
                if (u<n-m) ss[s[u+m]-'a'].set(m-1);
            }
        }
        else if (m<=40000){
            for (int i=0; i<m; ++i) sss[s[i]-'a'].set(i);
            for (int i=0; i<m; ++i) ttt[t[i]-'a'].set(i);
            for (int u=0; u<=n-m; ++u){
                int ret=0;
                for (int j=0; j<6; ++j) b[j]=0;
                for (int i=0; i<6; ++i)
                for (int j=0; j<6; ++j){
                    re[i][j]=0;
                    if (j!=i&&(sss[i]&ttt[j]).any()) re[i][j]=1;
                }
                for (int i=0; i<6; ++i) if (!b[i]) ret+=dfs(i)-1;
                printf("%d ",ret);
                for (int i=0; i<6; ++i) sss[i]>>=1;
                if (u<n-m) sss[s[u+m]-'a'].set(m-1);
            }
        }
        else if (m<=60010){
            for (int i=0; i<m; ++i) ssssss[s[i]-'a'].set(i);
            for (int i=0; i<m; ++i) tttttt[t[i]-'a'].set(i);
            for (int u=0; u<=n-m; ++u){
                int ret=0;
                for (int j=0; j<6; ++j) b[j]=0;
                for (int i=0; i<6; ++i)
                for (int j=0; j<6; ++j){
                    re[i][j]=0;
                    if (j!=i&&(ssssss[i]&tttttt[j]).any()) re[i][j]=1;
                }
                for (int i=0; i<6; ++i) if (!b[i]) ret+=dfs(i)-1;
                printf("%d ",ret);
                for (int i=0; i<6; ++i) ssssss[i]>>=1;
                if (u<n-m) ssssss[s[u+m]-'a'].set(m-1);
            }
        }
        else if (m<=80010){
            for (int i=0; i<m; ++i) ssss[s[i]-'a'].set(i);
            for (int i=0; i<m; ++i) tttt[t[i]-'a'].set(i);
            for (int u=0; u<=n-m; ++u){
                int ret=0;
                for (int j=0; j<6; ++j) b[j]=0;
                for (int i=0; i<6; ++i)
                for (int j=0; j<6; ++j){
                    re[i][j]=0;
                    if (j!=i&&(ssss[i]&tttt[j]).any()) re[i][j]=1;
                }
                for (int i=0; i<6; ++i) if (!b[i]) ret+=dfs(i)-1;
                printf("%d ",ret);
                for (int i=0; i<6; ++i) ssss[i]>>=1;
                if (u<n-m) ssss[s[u+m]-'a'].set(m-1);
            }
        }
        else{
            for (int i=0; i<m; ++i) sssss[s[i]-'a'].set(i);
            for (int i=0; i<m; ++i) ttttt[t[i]-'a'].set(i);
            for (int u=0; u<=n-m; ++u){
                int ret=0;
                for (int j=0; j<6; ++j) b[j]=0;
                for (int i=0; i<6; ++i)
                for (int j=0; j<6; ++j){
                    re[i][j]=0;
                    if (j!=i&&(sssss[i]&ttttt[j]).any()) re[i][j]=1;
                }
                for (int i=0; i<6; ++i) if (!b[i]) ret+=dfs(i)-1;
                printf("%d ",ret);
                for (int i=0; i<6; ++i) sssss[i]>>=1;
                if (u<n-m) sssss[s[u+m]-'a'].set(m-1);
            }
        }
    }
    View Code

    bitset不支持可变长度,于是就分类讨论,反正bitset空间很小。实测比写的xiang的FFT快。

    话说不是很懂Execution time Rank 1 的大佬的写法是什么?

  • 相关阅读:
    守护线程与普通线程
    Java中实现多线程的两种方式之间的区别
    Python os.dup() 方法
    Python os.closerange() 方法
    Python os.close() 方法
    Python os.chroot() 方法
    Python os.chmod() 方法
    JavaScript——基本包装类型
    javascript——function类型(this关键字)
    常用的正则
  • 原文地址:https://www.cnblogs.com/Yuhuger/p/8633965.html
Copyright © 2011-2022 走看看