LeetCode 第131场双周赛个人题解

100309. 求出出现两次数字的 XOR 值

原题链接

求出出现两次数字的 XOR 值 - 力扣 (LeetCode) 竞赛

思路分析

签到题,一次遍历

AC代码

class Solution:
    def duplicateNumbersXOR(self, nums: List[int]) -> int:
        cnt = Counter(nums)
        res = 0
        st = set(nums)
        for x in st:
            if cnt[x] == 2:
                res ^= x
        return res

100303. 查询数组中元素的出现位置

原题链接

  查询数组中元素的出现位置 - 力扣 (LeetCode) 竞赛

思路分析

  记录下每个次数的位置,然后遍历一下查询就行

时间复杂度O(n)

AC代码

class Solution:
    def occurrencesOfElement(self, nums: List[int], queries: List[int], x: int) -> List[int]:
        mp = defaultdict()
        s = 0
        for i, v in enumerate(nums):
            if v == x:
                s += 1
                mp[s] = i
        return [mp[v] if v in mp else -1 for v in queries]
            
            

100313. 所有球里面不同颜色的数目

原题链接

  所有球里面不同颜色的数目 - 力扣 (LeetCode) 竞赛

思路分析

  一开始敲了个莫队的板子,又看了下题看错题了。。。没那么复杂

边遍历边执行操作,边维护每个元素出现次数,然后记录下集合中的元素就行

时间复杂度O(n)

AC代码

class Solution:
    def queryResults(self, limit: int, queries: List[List[int]]) -> List[int]:
        cnt = Counter()
        mp = defaultdict(int)
        ret = []
        st = set()
        for x, y in queries:
            cnt[mp[x]] -= 1
            if cnt[mp[x]] == 0:
                st.remove(mp[x])
            mp[x] = y
            cnt[y] += 1
            st.add(y)
            ret.append(len(st))
        return ret

100314. 物块放置查询

原题链接

  物块放置查询 - 力扣 (LeetCode) 竞赛

思路分析

  思路就是线段树维护区间和,但是会卡常。

对原数轴重新编号

原数轴上的点i变为2 * i + 1,点与点之间的空隙也依次编号

然后空隙的权值为1,原数轴点的权值为0

在原数轴放障碍相当于将其赋值为负无穷

对于每个查询[0, x]等价于查询[1, 2 * x + 1]的最大连续子段和是否大于等于sz

我们只需要用线段树维护最大连续子段和即可

只涉及单点修改和区间查询,时间复杂度为O(nlogn)


由于拆点,区间长度为1e5量级,但是竟然被卡常了?

加个快读和吸氧才过

掉大分!!!

AC代码

#pragma GCC optimize(2)
const int N = 1e5 + 10;
#define lc p << 1
#define rc p << 1 | 1
struct node{
    int l, r;
    long long sum, lma, rma, ma;
}tr[N << 2];

int n, m, a[N];

void pushup(node& p, node& l, node& r){
    p.sum = l.sum + r.sum;
    p.lma = max(l.lma, l.sum + r.lma);
    p.rma = max(r.rma, r.sum + l.rma);
    p.ma = max(l.rma + r.lma, max(l.ma, r.ma));
}

void build(int p, int l, int r){
    tr[p] = { l, r, 0, 0, 0, 0 };
    if(l == r){
        if (l % 2 == 0) tr[p] = { l, l, 1, 1, 1, 1 };
        return;
    }
    int mid = l + r >> 1;
    build(lc, l, mid), build(rc, mid + 1, r);
    pushup(tr[p], tr[lc], tr[rc]);
}

node query(int p, int l, int r){
    if(l <= tr[p].l && tr[p].r <= r)
        return tr[p];
    int mid = tr[p].l + tr[p].r >> 1;
    if(r <= mid) return query(lc, l, r);
    else if(l > mid) return query(rc, l, r);
    node left = query(lc, l, r);
    node right = query(rc, l, r);
    node ret = { 0 };
    pushup(ret, left, right);
    return ret;
}

void update(int p, int x, int k){ //点修
    if(tr[p].l == x && tr[p].r == x){
        tr[p] = { x, x, k, k, k, k };
        return;
    }
    int mid = tr[p].l + tr[p].r >> 1;
    if(x <= mid) update(lc, x, k);
    else update(rc, x, k);
    pushup(tr[p], tr[lc], tr[rc]);
}


class Solution {
public:
    Solution() {
        ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    }
    vector<bool> getResults(vector<vector<int>>& queries) {
        memset(tr, 0, sizeof tr);
        build(1, 1, N);
        vector<bool> ret;
        for (auto& v : queries) {
            int op = v[0];
            if (op == 1) {
                update(1, v[1] * 2 + 1, -1e8);
            }
            else {
                auto t = query(1, 1, v[1] * 2 + 1);
                ret.push_back(t.ma >= v[2]);
            }
        }
        return ret;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

EQUINOX1

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

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

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

打赏作者

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

抵扣说明:

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

余额充值