Codeforces Round #830 (Div. 2)C,D补题

147 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情
本文已参与「新人创作礼」活动,一 起开启掘金创作之路

C1

This is the easy version of the problem. The only difference is that in this version q=1q = 1. You are given an array of integers a1,a2,,ana_1, a_2, \ldots, a_n. The cost of a subsegment of the array [l,r][l, r], 1lrn1 \leq l \leq r \leq n, is the value f(l,r)=sum(l,r)xor(l,r)f(l, r) = \operatorname{sum}(l, r) - \operatorname{xor}(l, r), where sum(l,r)=al+al+1++ar\operatorname{sum}(l, r) = a_l + a_{l+1} + \ldots + a_r, and xor(l,r)=alal+1ar\operatorname{xor}(l, r) = a_l \oplus a_{l+1} \oplus \ldots \oplus a_r (\oplus stands for bitwise XOR). You will have q=1q = 1 query. Each query is given by a pair of numbers LiL_i, RiR_i, where 1LiRin1 \leq L_i \leq R_i \leq n. You need to find the subsegment [l,r][l, r], LilrRiL_i \leq l \leq r \leq R_i, with maximum value f(l,r)f(l, r). If there are several answers, then among them you need to find a subsegment with the minimum length, that is, the minimum value of rl+1r - l + 1.

中文大意

给我们n个数字让我们求出11~nn中一段区间的和减去这段区间的异或值差值最大并且长度最小

解法

因为这个我们很容易想到前缀和和前缀异或和,所以我们一开始就可以执行这个操作根据异或的性质我们可以知道异或是不进位加法由此可以知道随着ii的增加那么他们的差值也一定是跟着增加的所以我们就可以知道了最大差值一定是nn11之间的所以这道题目也有了二分性直接二分即可

int a[N];
int l[N],r[N];
void solve()
{
   int n,q; cin >> n >> q;
   rep(i,n) cin >> a[i];
   rep(i,n) {
     l[i] = l[i-1] + a[i];
     r[i] = r[i-1] ^ a[i];
   }
   int res = l[n] - r[n];
   int L,R;
   cin >> L >> R;
   int resl = 0,resr = 0;
   auto check = [&](int x) {
      for(int i=1;i+x-1<=n;i++)
        if(l[i+x-1]-l[i-1]-(r[i+x-1]^r[i-1])== res)
            return resl=i,resr=i+x-1,1;
    return 0;
   };
   while( L <= R) {
     int mid = L + R >> 1;
     if(check(mid)) R = mid - 1;
     else L = mid + 1;
   }
   cout << resl << ' ' << resr << endl;
}