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\n", maxans, lsh[pos]);
   return 0;
}

猜你喜欢

转载自www.cnblogs.com/riju-yuezhu/p/13192826.html
今日推荐