leetcode 第233场周赛

第三题:1802. 有界数组中指定下标处的最大值

思路:最值,二分法,check。分类左右两侧与x的大小关系

class Solution {
public:
    bool judge(int x, int n, int index, int maxSum) {
        long long sum = 0;
        if(x <= index+1) sum = sum + 1ll*(1+x)*x/2 + index+1-x;
        else  sum += 1ll*(2*x-index)*(index+1)/2;
        if(x-1 <= n-1-index)  sum += 1ll*x*(x-1)/2 + n-index-x;
        else  sum = sum + 1ll*(2*x-n+index)*(n-1-index)/2;
        return sum <= maxSum;
    }
    int maxValue(int n, int index, int maxSum) {
        int l = 1, r = 1e9+1, ans;
        while(l <= r) {
            int mid = (l+r)>>1;
            if(judge(mid,n,index,maxSum)) {
                ans = mid;
                l = mid+1;
            } else {
                r = mid-1;
            }
        }
        return ans;
    }
};

第四题:1803. 统计异或值在范围内的数对有多少

思路:异或值,字典树。查询与x异或值小于limit的个数。

class Solution {
public:
    #define maxnode 32*20000+10
    #define sigma 2
    struct Trie {
        int ch[maxnode][sigma];
        // int value[maxnode]; //  叶子节点的值
        int cnt[maxnode];   // 经该节点的元素个数
        int sz = 1;

        void init(){
            memset(ch, 0 ,sizeof(ch));
            memset(cnt, 0, sizeof(cnt));
        }
    
        void insert(int x){
            int u = 0;
            for(int i = 31; i >= 0; i--){
                int c = (x>>i)&1;
                if(!ch[u][c])  ch[u][c] = sz++;
                u = ch[u][c];
                cnt[u]++;
            }
        }

        // 查询与x异或,结果小于limit的数的个数
        int query(int x, int limit){
            int u = 0, res = 0;
            for(int i = 31; i >= 0; --i){
                int a = (x>>i)&1, b = (limit>>i)&1;
                if(a == 0 && b == 0)  u = ch[u][0];
                if(a == 0 && b == 1)  res += cnt[ch[u][0]], u = ch[u][1];
                if(a == 1 && b == 0)  u = ch[u][1];
                if(a == 1 && b == 1)  res += cnt[ch[u][1]], u = ch[u][0];  
                if(!u)  break;
            }
            return res;
        }
    }trie;



    int countPairs(vector<int>& nums, int low, int high) {
        trie.init();
        for(int num : nums)  trie.insert(num);
        int n = nums.size(), ans = 0;
        for(int i = 0;i < n;i++) {
            // cout << trie.query(nums[i], high) << " " << trie.query(nums[i], low-1) << endl;
            ans = ans + trie.query(nums[i], high+1) - trie.query(nums[i], low);
        }
        return ans/2;  // 一对算了两遍
    }
};
个性签名:时间会解决一切
原文地址:https://www.cnblogs.com/lfri/p/14570290.html