zoukankan      html  css  js  c++  java
  • [XJOI3529] 左右

    题目链接:左右

    Description

    给你一个s数组,一个t数组,你可以对s数组执行以下两种操作
    L 操作:每个数等于其左边的数加上自己
    R 操作:每个数等于其右边的数加上自己
    第一个数的左边是最后一个数,最后一个数的右边是第一个数
    对于每个操作,所有的加法是同时进行的,即(new)s[i] = (old)s[i - 1] + (old)s[i]
    现在问你s数组能否变成t数组。
    数据范围 (1le nle 50, 1le s_i, t_ile 10^{15})

    Solution

    引理:只要确定了(L)(R)的次数,无论按什么顺序操作,最终序列都相同。
    我们将这个数列视为一个多项式,并以(0,1,...,n-1)作为下标,则:
    序列为(a_0,a_1x,a_2x^2,...,a_{n-1}x^{n-1})
    (L)操作等价于这个式子乘以((1+x)),指数对(n)取模。
    (R)操作等价于这个式子乘以((1+x^{n-1})),指数对(n)取模。
    我们发现,(L)(R)操作的顺序并不影响序列的结果。
    那么我们可以暴力枚举(L)(R)的次数,并且直接模拟即可。
    注意到,因为上限是(10^{15}),所以最多只需要(L)(R)操作(log)次即可。
    复杂度 (O(n^3)),跑不满。

    Code

    // Author: wlzhouzhuan
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #include <bits/stdc++.h>
    using namespace std;
     
    #define ll long long
    #define ull unsigned long long
    #define rint register int
    #define rep(i, l, r) for (rint i = l; i <= r; i++)
    #define per(i, l, r) for (rint i = l; i >= r; i--)
    #define mset(s, _) memset(s, _, sizeof(s))
    #define pb push_back
    #define pii pair <int, int>
    #define mp(a, b) make_pair(a, b)
     
    inline int read() {
      int x = 0, neg = 1; char op = getchar();
      while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
      while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
      return neg * x;
    }
    inline void print(int x) {
      if (x < 0) { putchar('-'); x = -x; }
      if (x >= 10) print(x / 10);
      putchar(x % 10 + '0');
    }
     
    const int N = 102;
    ll a[N], b[N], n;
    ll c[N], d[N];
    
    bool check() {
      for (int i = 1; i <= n; i++) if (c[i] != b[i]) return 0;
      return 1; 
    }
    int main() {
      cin >> n;
      for (int i = 1; i <= n; i++) cin >> a[i];
      for (int i = 1; i <= n; i++) cin >> b[i];
      for (int a1 = 0; a1 <= 50; a1++) {
        for (int i = 1; i <= n; i++) c[i] = a[i];
        int ok = 1;
        for (int k = 1; k <= a1; k++) {
          for (int i = 1; i <= n; i++) d[i] = c[i] + c[i == 1 ? n : i - 1];
          for (int i = 1; i <= n; i++) {
            c[i] = d[i];
            if (c[i] > b[i]) {
              ok = 0;
              break;
            }
          }
        }
        if (!ok) continue;
        int a2 = 50;
        while (a2--) { 
          if (check()) {
            puts("Yes");
            exit(0);
          }
          for (int i = 1; i <= n; i++) d[i] = c[i] + c[i == n ? 1 : i + 1];
          for (int i = 1; i <= n; i++) {
            c[i] = d[i];
            if (c[i] > b[i]) {
              break;
            }
          }
        } 
      }
      puts("No");
      return 0;
    }
    
  • 相关阅读:
    luoguP1829 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演)
    luoguP1447 [NOI2010]能量采集
    POJ2559 Largest Rectangle in a Histogram (单调栈
    2038: [2009国家集训队]小Z的袜子(hose)
    codeforces 835C Star sky
    HDU1859 最小长方形 (水
    HDU 1754 I Hate It
    HDU 1698 Just a Hook(线段树
    HDU 1394 Minimum Inversion Number(树状数组/归并排序实现
    HDU1166 敌兵布阵(树状数组实现
  • 原文地址:https://www.cnblogs.com/wlzhouzhuan/p/12747625.html
Copyright © 2011-2022 走看看