给定长度为n的数组a,定义f(l, r) = (a[l]+...+a[r])-(a[l]^...^a[r]),有q次询问:L,R,求对于L<=l<=r<=R, f(l, r)取最大值时l,r的值

文章描述了一种算法,用于在一个动态修改的数组中,给定查询范围L和R,找到使(r-l+1)最小且f(l,r)取最大值的区间[l,r]。使用了二分查找和前缀和计算来提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

若f(l, r) 取最大值时l,r有多种可能,求r - l + 1最小的l,r。

题目

思路:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define fi first
#define se second
#define lson p << 1
#define rson p << 1 | 1
const int maxn = 1e6 + 5, inf = 1e9, maxm = 4e4 + 5, mod = 998244353, N = 1e6;
int a[maxn], b[maxn];
int n, m;
string s;
int sum[maxn];
int Xor[maxn];

void solve(){
    int res = 0;
    // int k;
    int x;
    int q;
    cin >> n;
    cin >> q;
    int L, R;
    // int Xor = 0, sum = 0;
    vector<int> p;
    p.pb(0);
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        if(a[i]){
            p.pb(i);
        }
    }
    int m = p.size() - 1;
    for(int i = 1; i <= m; i++){
        sum[i] = sum[i - 1] + a[p[i]];
        Xor[i] = Xor[i - 1] ^ a[p[i]];
    }
    int num = 0;
    while(q--){
        num++;
        cin >> L >> R;
        if(!m){
            cout << L << ' ' << L << '\n';
            continue;
        }
        int x = lower_bound(p.begin() + 1, p.end(), L) - p.begin();
        int y = upper_bound(p.begin() + 1, p.end(), R) - p.begin();
        y--;
        if(x > y){
            cout << L << ' ' << L << '\n';
            continue;
        }
        L = p[x], R = p[y];
        // cout << x << ' ' << y << '\n';
        int l = p[x], r = p[y];
        int mx = (sum[y] - sum[x - 1]) - (Xor[y] ^ Xor[x - 1]);
        for(int i = x; i <= min(y, x + 32); i++){
            for(int j = max(i, y - 32); j <= y; j++){
                int tmp = (sum[j] - sum[i - 1]) - (Xor[j] ^ Xor[i - 1]);
                if(tmp == mx){
                    if(p[j] - p[i] + 1 < r - l + 1){
                        l = p[i];
                        r = p[j];
                    }
                }
            }
        }
        if(l > r){
            l = L, r = L;
        }
        cout << l << ' ' << r << '\n';
    }
}
    
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    // fac[0] = 1;
    // for(int i = 1; i <= N; i++){
    //     fac[i] = fac[i - 1] * i % mod;
    // }
    int T = 1;
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__night_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值