zoukankan      html  css  js  c++  java
  • [CF1045B]Space Isaac

    题目:Space Isaac

    传送门:http://codeforces.com/contest/1045/problem/B

    分析:

    1)我们考虑不能被表示出来的数。

    2)设这个数为P,对所有的数x,如果$x in A$,在那么$(p-x)mod m in A $;如果$x in B$,在那么$(p-x)mod m in B $。否则显然可以表示出这个数。

    3)$x$可以分为两段: 小于$P$和大于$P$的情况。当$x<P$时 $P-x<P$;$x>P$时$P-x>P$。

    4)考虑枚举分段点$i$,$P=(a[1]+a[i])%m=(a[2]+a[i-1])%m=...$,这就类似个回文串啊。比$P$大的部分同理。

    5)然后就是这段经典操作,$b[i]=a[i+1]-a[i];$,再求回文串了。

    方法一:

    6)回文串可以哈希,顺着、反着各一遍求区间hash值,然后比较是否相等,

    7)哈希基于概率,有可能会冲突,简单的做法是双哈希,就是这么暴力,如果还不能解决,那就再来一遍。

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ULL; 
    const int maxN=200005;
    const ULL HA=41793404541;
    int n,m;
    int a[maxN],b[maxN];
    ULL fac[maxN],pre[maxN],nxt[maxN];
    int ansn,ans[maxN];
    bool check(int l,int r){
        return pre[r]-pre[l-1]*fac[r-l+1]==nxt[l]-nxt[r+1]*fac[r-l+1];
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)scanf("%d",&a[i]);
        for(int i=1;i< n;++i)b[i]=a[i+1]-a[i];
        fac[0]=1;
        for(int i=1;i<=n;++i)fac[i]=fac[i-1]*HA;
        for(int i=1;i<=n;++i)pre[i]=pre[i-1]*HA+(ULL)b[i];
        for(int i=n-1;i ;--i)nxt[i]=nxt[i+1]*HA+(ULL)b[i];
        for(int i=1;i<=n;++i){
            bool pd=true;
            if(i!=1)pd&=check(1,i-1);
            if(i!=n){
                pd&=(a[1]+a[i]==a[i+1]+a[n]-m);
                if(i!=n-1)pd&=check(i+1,n-1);
            }
            if(pd)ans[++ansn]=(a[1]+a[i])%m;
        }
        printf("%d
    ",ansn);
        sort(ans+1,ans+ansn+1);
        for(int i=1;i<=ansn;++i)printf("%d ",ans[i]);
        return 0;
    }

    方法二

    8)manachar也是用来解决回文串的有力武器,这里先埋一个坑,捂脸逃。。

    题外:

    这种题现场过的都是神仙(大雾

  • 相关阅读:
    04_Windows平台Spark开发环境构建
    Hadoop Streaming 使用及参数设置
    Kafka 及 PyKafka 的使用
    Database Subquery
    Miscellaneous
    Emacs
    算法归纳
    逆元求组合数
    Elasticsearch 原理
    Linux的内存分页管理【转】
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/10390050.html
Copyright © 2011-2022 走看看