P6627 [省选联考 2020 B 卷] 幸运数字

Posted riju-yuezhu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P6627 [省选联考 2020 B 卷] 幸运数字相关的知识,希望对你有一定的参考价值。

P6627 [省选联考 2020 B 卷] 幸运数字

这道题乍一看的确挺简单,但是我就是写挂了(统计答案的锅)。100->35,省队无。

看完后就会发现:你只需要维护一个区间异或的操作,并且不需要在线修改。

那么,差分不就完事了吗。

//在[l,r]上对a[i]进行区间异或
a[l] ^= w, a[r] ^= w;

//最后统计答案前
for(int i = 2; i <= n; i++) a[i] ^= a[i-1];

那么,只要离散化数据,很轻松地就可以完成这个操作。由于要离散化,时复O(nlogn)


那么,统计答案怎么办呢?

我们来找找答案在哪里把。

首先,我们肯定要把那些询问的边界(A, B, L, R)(姑且称为边界点)保存下来,这些东西当然可能成为答案。

其次,我们发现,两个相邻的边界点(比如叫做(A)(B))之间的一段区间([A+1,B-1])的答案必定是相同的。那么答案可能在这个区间上。那么问题来了:到底在哪里呢?根据这个鬼畜的答案统计规则,我们可以发现,它必定在区间的两端(即(A+1)(B-1))或(0)处。

所以这样统计就好了。

记得数组空间开大!!!

#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll read() {
   ll x = 0, f = 1; char ch = getchar();
   for(; ch < ‘0‘ || ch > ‘9‘; ch = getchar()) if(ch == ‘-‘) f = -1;
   for(; ch >= ‘0‘ && ch <= ‘9‘; ch = getchar()) x = x * 10 + ch - ‘0‘;
   return x * f;
}
const int MAXN = 1e5 + 5;
int n;
struct Node {
   int t, x, y, w;

}q[MAXN];
int lsh[MAXN  * 6], tot;
void LSH() {
   sort(lsh + 1, lsh + 1 + tot);
   tot = unique(lsh + 1, lsh + 1 + tot) - lsh - 1;
}
int LSH(int x) {
   return lower_bound(lsh + 1, lsh + 1 + tot, x) - lsh;
}
int a[MAXN * 6];
int maxans, pos;
int main() {
   n = read();
   for(int i = 1; i <= n; i++) {
      Node& now = q[i];
      now.t = read();
      if(now.t == 1)
         now.x = read(), now.y = read();
      else if(now.t == 2)
         now.x = read();
      else now.y = read();
      lsh[++tot] = now.x;
      lsh[++tot] = now.x - 1;
      lsh[++tot] = now.x + 1;
      lsh[++tot] = now.y;
      lsh[++tot] = now.y - 1;
      lsh[++tot] = now.y + 1;
      now.w = read();
   }
   lsh[++tot] = 0;
   LSH();
   for(int i = 1; i <= n; i++) {
      Node& now = q[i];
      int tx = LSH(now.x), ty = LSH(now.y);
      if(now.t == 1) a[tx] ^= now.w, a[ty + 1] ^= now.w;
      else if(now.t == 2) a[tx] ^= now.w, a[tx + 1] ^= now.w;
      else a[1] ^= now.w, a[ty] ^= now.w, a[ty + 1] ^= now.w;
   }
   for(int i = 2; i <= tot; i++) a[i] ^= a[i - 1];
   maxans = a[1]; pos = 1;
   for(int i = 2; i <= tot; i++) {
      if(maxans < a[i]) maxans = a[i], pos = i;
      else if(maxans == a[i]) {
         if(abs(lsh[i]) < abs(lsh[pos])) maxans = a[i], pos = i;
         else if(abs(lsh[i]) == abs(lsh[pos]) && lsh[i] > lsh[pos]) maxans = a[i], pos = i;
      }
   }
   printf("%d %d
", maxans, lsh[pos]);
   return 0;
}

以上是关于P6627 [省选联考 2020 B 卷] 幸运数字的主要内容,如果未能解决你的问题,请参考以下文章

luoguP6620 [省选联考 2020 A 卷] 组合数问题(斯特林数)

[省选联考 2020 A 卷] 组合数问题 题解

P6625 [省选联考 2020 B 卷] 卡牌游戏

场外模拟 省选联考(A卷重考) 2020 游记

luoguP6623 [省选联考 2020 A 卷] 树(trie树)

题解 省选联考2020 组合数问题