• Codeforces 1045B Space Isaac


    题目传送门

      传送门I

      传送门II

      传送门III

    题目大意

      给定将$left { 0, 1, dots, m - 1 ight }$分成了不相交的两个非空集合$A$和$B$,给定$A$,问存在多少个整数$x$满足$0leqslant x < m$且对于任意$ain A, b in B$满足$a + b ot equiv x pmod{m}$

      容易发现满足后一个条件的充分必要条件是对于任意$a in A$,存在$a' in A$使得$a + a' equiv x pmod{m}$。

      如果$a leqslant x$,则易证$a' leqslant x$。

      同样,如果$a > x$,则易证$a' > x$。

      所以这个数$x$将序列分成两部分,每一部分首尾配对后,每一对的和都等于$x$。

      那么怎么判断呢?我们发现$a + d = c + b$等价于$a - b = c - d$。

      所以我们只用差分一下判断是否是回文,再判断首尾的和是否等于$x$就行了。

    Code

     1 /**
     2  * Codeforces
     3  * Problem#1045B
     4  * Accepted
     5  * Time: 77ms
     6  * Memory: 7300k
     7  */
     8 #include <algorithm>
     9 #include <iostream>
    10 #include <cstdlib>
    11 #include <cstdio>
    12 #include <vector>
    13 using namespace std;
    14 typedef bool boolean;
    15 
    16 #define ull unsigned long long
    17 
    18 const int N = 2e5 + 5;
    19 const ull base = 1e9 + 7;
    20 
    21 int n, M;
    22 int ar[N];
    23 int cr[N];
    24 ull ph[N], sh[N], pb[N];
    25 
    26 int add(int a, int b) {
    27     return ((a += b) >= M) ? (a - M) : (a);
    28 }
    29 
    30 inline void init() {
    31     scanf("%d%d", &n, &M);
    32     for (int i = 1; i <= n; i++)
    33         scanf("%d", ar + i);
    34 }
    35 
    36 ull fquery(int l, int r) {    // forward
    37     if (l > r)
    38         return 0;
    39     return ph[r] - ph[l - 1] * pb[r - l + 1];
    40 }
    41 
    42 ull rquery(int l, int r) {    // backward
    43     if (l > r)
    44         return 0;
    45     return sh[l] - sh[r + 1] * pb[r - l + 1];
    46 }
    47 
    48 boolean ispar(int l, int r) {
    49     return fquery(l, r) == rquery(l, r);
    50 }
    51 
    52 vector<int> vec;
    53 
    54 inline void solve() {
    55     ph[0] = 0, sh[n] = 0, pb[0] = 1;
    56     for (int i = 1; i < n; i++)
    57         ph[i] = ph[i - 1] * base + (cr[i] = ar[i + 1] - ar[i]);
    58     for (int i = n - 1; i; i--)
    59         sh[i] = sh[i + 1] * base + cr[i];
    60     for (int i = 1; i < n; i++)
    61         pb[i] = pb[i - 1] * base;
    62 
    63     for (int i = 1, x; i < n; i++) {
    64         x = ar[1] + ar[i];
    65 //        if (x >= M)
    66 //            break;
    67         if (add(ar[i + 1], ar[n]) == x && ispar(1, i - 1) && ispar(i + 1, n - 1))
    68             vec.push_back(x);
    69     }
    70     int x = add(ar[1], ar[n]);
    71     if ((x <= ar[1] || x >= ar[n]) && ispar(1, n - 1))
    72         vec.push_back(x);
    73     printf("%d
    ", (signed) vec.size());
    74     sort(vec.begin(), vec.end());
    75     for (int i = 0; i < (signed) vec.size(); i++)
    76         printf("%d ", vec[i]);
    77     putchar('
    ');
    78 }
    79 
    80 int main() {
    81     init();
    82     solve();
    83     return 0;
    84 }
  • 相关阅读:
    Thinkphp3.2.3关于开启DEBUG正常,关闭DEBUG就报错模版无法找到,页面错误!请稍后再试~
    Apache 工作模式的正确配置
    TIME_WAIT 你好!
    对称加密实现重要日志上报Openresty接口服务
    阿里nas挂载错误
    机器装多个版本php,并安装redis插件报错【已解决】
    find 删除文件
    从头认识java-6.7 初始化与类的加载
    从头认识java-6.6 final(4)-类与忠告
    从头认识java-6.6 final(3)-方法
  • 原文地址:https://www.cnblogs.com/yyf0309/p/9808323.html
Copyright © 2020-2023  润新知