首页 > 其他分享 >Codeforces 452F Permutation

Codeforces 452F Permutation

时间:2024-05-03 15:33:04浏览次数:26  
标签:__ return && Codeforces constexpr u128 ull Permutation 452F

对于 \(a, b, \frac{a + b}{2}\) 肯定是需要固定下一些变量来考虑的。

考虑固定下 \(c = \frac{a + b}{2}\),考虑 \(a, b\)。
那么这样的 \(a, b\) 肯定满足 \(a - c = b - c, a\not = b\),那么以 \(c\) 为中心,\(a, b\) 就是对称的。
用 \(s_i = 0, 1\) 来表示 \(i\) 是在 \(c\) 的左边或是右边。
无解就是对于每个 \(c\),每组关于 \(c\) 对称的 \(a, b\) 都满足 \(s_a = s_b\)。

这个条件转化一下就是令边界的关于 \(c\) 对称的对为 \(x, y(x = 1\lor y = n)\),\(s_{x\sim y}\) 为回文串。

那么就可以用线段树维护 \(\text{Hash}\),从左往右扫过去的时候修改对应的 \(s_i\),然后查询一下区间正反的 \(\text{Hash}\) 进行比较。

时间复杂度 \(\mathcal{O}(n\log n)\)。

代码
#include<bits/stdc++.h>
using ull = unsigned long long;
using u128 = __uint128_t;
constexpr inline u128 qpow(u128 a, u128 b, ull p, u128 v = 1) {
   while (b) {
      b & 1 && ((v *= a) %= p);
      (a *= a) %= p, b >>= 1;
   }
   return v;
}
constexpr inline bool checkpr(ull p) {
   int a = __builtin_ctzll(p - 1);
   ull b = p - 1 >> a;
   for (ull v : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) {
      u128 x = qpow(v, b, p), y = 0;
      for (int c = 0; c < a; c++, x = y) {
         y = x * x % p;
         if (y == 1 && x != 1 && x != p - 1)
            return false;
      }
      if (x != 1)
         return false;
   }
   return true;
}
constexpr inline ull getpr(ull l, ull r) {
   ull x = 0;
   for (int v : __DATE__ __TIME__ __TIMESTAMP__) x ^= (x + v) << 13;
   while (true) {
      x ^= x << 13, x ^= x >> 7, x ^= x << 17;
      ull y = l + x % (r - l);
      if (checkpr(y)) return y;
   }
   return 0;
}
constexpr ull P = getpr((ull)1e3, (ull)1e5), mod = getpr((ull)1e6, (ull)1e7);
const int maxn = 3e5 + 10;
int n;
struct node_t {
   ull v, b;
   inline node_t(ull v_ = 0, ull b_ = 0) {
      v = v_, b = b_;
   }
   inline node_t operator + (const node_t &a) const {
      return node_t((v * a.b + a.v) % mod, (b * a.b) % mod);
   }
} tr[maxn * 4][2];
inline void pushup(int k) {
   tr[k][0] = tr[k << 1][0] + tr[k << 1 | 1][0];
   tr[k][1] = tr[k << 1 | 1][1] + tr[k << 1][1];
}
void upd(int x, int y, int k = 1, int l = 1, int r = n) {
   if (l == r)
      return tr[k][0] = tr[k][1] = node_t(y, P), void();
   int mid = (l + r) >> 1;
   x <= mid ? upd(x, y, k << 1, l, mid) : upd(x, y, k << 1 | 1, mid + 1, r);
   pushup(k);
}
node_t qry(int x, int y, int op, int k = 1, int l = 1, int r = n) {
   if (x <= l && r <= y) return tr[k][op];
   int mid = (l + r) >> 1;
   if (y <= mid) return qry(x, y, op, k << 1, l, mid);
   if (mid < x) return qry(x, y, op, k << 1 | 1, mid + 1, r);
   node_t L = qry(x, y, op, k << 1, l, mid), R = qry(x, y, op, k << 1 | 1, mid + 1, r);
   return ! op ? (L + R) : (R + L);
}
void build(int k = 1, int l = 1, int r = n) {
   if (l == r)
      return tr[k][0] = tr[k][1] = node_t(0, P), void();
   int mid = (l + r) >> 1;
   build(k << 1, l, mid), build(k << 1 | 1, mid + 1, r);
   pushup(k);
}
int a[maxn];
int main() {
   scanf("%d", &n);
   for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
   build();
   for (int i = 1; i <= n; i++) {
      int len = std::min(a[i] - 1, n - a[i]), l = a[i] - len, r = a[i] + len;
      if (qry(l, r, 0).v != qry(l, r, 1).v)
         return puts("YES"), 0;
      upd(a[i], 1);
   }
   return puts("NO"), 0;
}

标签:__,return,&&,Codeforces,constexpr,u128,ull,Permutation,452F
From: https://www.cnblogs.com/rizynvu/p/18171255

相关文章

  • Codeforces 1044F DFS
    考虑到存在方案使得以\(u\)为起点还能走出原树的条件。能发现是以\(u\)为根,在原树上新添加的边只会是返祖边而不会有横叉边。这是因为如果有横叉边就肯定会在遍历到一边的点后先通过这条边走到另一边的点,就算上了这条边就不是原树了。那么考虑\((x,y)\),合法的\(u\)需要......
  • Educational Codeforces Round 165 (Rated for Div. 2) C. Minimizing the Sum题解
    题意CodeforcesRound809(Div.2)D1.ChoppingCarrots(EasyVersion)给你两个整数\(n(1\len\le3e5),k(0\lek\le10)\),一个数组\(a(1\lea_i\le10^9)\)。你可以进行如下操作最多\(k\)次:选定一个数\(i(1\lei\len)\),让其变为相邻的数(变为\(a_{i-1},a_{i......
  • Codeforces Round 942 (Div. 2) (A - E)
    A.ContestProposal如果\(a_i>b_i\),则答案加一,令\(\foralli\in[i+1,n],\a_i\leftarrowa_{i-1}\)。submissionB.CoinGames题意:\(n\)枚硬币围成一圈,给出初始硬币状态,每取出一枚正面朝上的硬币并翻转相邻的两枚,没有正面则对方获胜,问先手胜负。令当前正面硬......
  • Codeforces Round 942 (Div. 2)
    CodeforcesRound942(Div.2)A.ContestProposal题意:有n个题目,每个题目的难度为a[i],要求每个题目的难度不大于对应的b[i],每次可以添加一个题目并且删去最难的题目,求最多能添加几个题目思路:暴力枚举即可,只要a[i]大于b[i],就把a[n]改为b[i],然后重新排序voidsolve(){int......
  • Codeforces Round 942 Div.2 题解
    蹭个热度,挽救一下cnblogs蒸蒸日上的阅读量。Q:你是手速狗吗?A:我觉得我是。2A因为选的\(w\)一定可以让它合法,一次操作可以看作\(a\)数组向右平移一位。枚举操作次数后暴力判断即可。#include<bits/stdc++.h>voidwork(){ intn; std::cin>>n; std::vector<......
  • Educational Codeforces Round 165 (Rated for Div. 2) 题解
    A对于\(i\top_i\)连边。如果存在二元环,则答案为2。否则答案为3。B非降序排序:0全部在1前面。令0的个数为z。从左往右,将前z个全部填上0。填第\(i\)位时,每次填的最小代价为:若第\(i\)位为1,第\(i\)位右边的第一个0到\(i\)之间的字符个数。(贪心)......
  • Codeforces Round 921 (Div. 1)
    CF1924A签到题CF1924B用set记录每个关键点的位置,每次操作带来的影响可以转化为区间加和区间乘。结果在longlong范围内但过程中可能会超。比较tricky的做法是找一个大于ans的大质数p。在\(GF(p)\)上计算。非常坏卡常CF1924C小学奥数,注意到每次折叠产生的两种折痕长度相等。前......
  • permutations and combinations in js All In One
    permutationsandcombinationsinjsAllInOnejs中的排列组合概念排列组合demos/*permutations&combinations排列&组合https://leetcode.com/problems/3sum/给定一个数字数组,找出有三个元素为一组构成的所有不重复的子数字数组!*///constarr=[1,2,......
  • Educational Codeforces Round 164 (Div. 2)
    A-PaintingtheRibbon难度:⭐⭐解题思路先看特殊情况,如果m为1肯定不行,n小于等于k也不行;我们可以换位思考,如果Alice用了x种颜色,Bob想把其染为同一种颜色,肯定要先找出这x种颜色中染色区域最多的那一种,然后把其他区域的颜色换成该颜色,这样才是最优策略,所......
  • Educational Codeforces Round 164
    A-C简单数学题先跳过了,E题水平有限,暂时写不出来下面是D的题意ColoredBall(https://codeforces.com/contest/1954/problem/D)看题目,对于初学者来说,可能不知道使用DP怎么联想到DP的可能还是经验问题下面是个人对题目的拙见题目要求所有幂集组合里需要至少需要多少个二元对才......