• 【luogu P2801】 教主的魔法


    传送门:https://www.luogu.org/problemnew/show/P2801

      这道题刚看到的时候感觉就是线段树的两种操作嘛,维护一棵线段树就好了。然并卵我忘记线段树怎么写了。然后就想到打暴力水过数据点,就花了十来分钟打暴力,搞过了样例。但是。。。。最后得了0分,其他巨佬同样写了暴力拿到了100分(果然是我太菜了)。

      后来改题的时候看了眼题解,说是要用分块(早已遗忘了分块),然后就花了挺长时间写了分块,在洛谷上提交还是tle了一个点,但是算了一下复杂度是O(msqrt(nlogn)),并没有超数据范围(咱也不知道,咱也不敢问QAQ)最后开了o2,那个点就过了(玄学)。。。

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstring>
    typedef long long ll;
    using namespace std;
    const int maxn = 1000005;
    int n, m, block;
    int v[maxn], bel[maxn], tag[maxn];
    vector<int>vec[10005];
    void reset(int x) {
        vec[x].clear();
        for(int i = (x - 1) * block + 1; i <= min(x * block,n); i++)
            vec[x].push_back(v[i]);
        sort(vec[x].begin(),vec[x].end());
    }
    ll read()                               
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void add(int a, int b, int c) {
        for(int i = a; i <= min(bel[a] * block,b); i++)
            v[i] += c;
        reset(bel[a]);
        if(bel[a] != bel[b]) {
            for(int i = (bel[b] - 1) * block + 1; i <= b; i++)
                v[i] += c;
            reset(bel[b]);
        }
        for(int i = bel[a]+ 1; i <= bel[b] - 1; i++)
            tag[i] += c;
    }
    int query(int a, int b, int c) {
        int ans = 0;
        for(int i = a; i <= min(bel[a] * block,b); i++)
            if(v[i] + tag[bel[a]] < c)
                ans++;
        if(bel[a] != bel[b]) {
            for(int i = (bel[b] - 1) * block + 1; i <= b; i++)
                if(v[i] + tag[bel[b]] < c)
                    ans++;
        }
        for(int i = bel[a] + 1; i <= bel[b] - 1; i++) {
            int x = c - tag[i];
            ans += lower_bound(vec[i].begin(),vec[i].end(),x) - vec[i].begin();
        }
        return ans;
    }
    int main() {
        n = read(), m = read();
        block = sqrt(n);
        for(int i = 1; i <= n; i++)
            v[i] = read();
        for(int i = 1; i <= n; i++) {
            bel[i] = (i - 1) / block + 1;
            vec[bel[i]].push_back(v[i]);
        }
        for(int i = 1; i <= bel[n]; i++)
            sort(vec[i].begin(),vec[i].end());
        for(int i = 1; i <= m; i++) {
            char f[5];
            scanf("%s", f);
            int a = read(), b = read(), c = read();
            if(f[0] == 'M')
                add(a,b,c);
            else
                printf("%d
    ",b - a + 1 - query(a,b,c));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【PyTorch】PyTorch使用LMDB数据库加速文件读取
    【PyTorch】PyTorch中的梯度累加
    【数字图像处理】Bilateral Filters
    【PyTorch】计算局部相似矩阵
    【模型压缩】蒸馏算法小结
    【深度聚类】Superpixel Sampling Networks
    【PyTorch】训练器设置
    【语义分割】Dual Attention Network for Scene Segmentation
    【网络架构】Convolutional LSTM Network: A Machine Learning Approach for Precipitation Nowcasting
    【任务指标】Matting任务里的Gradient与Connectivity指标
  • 原文地址:https://www.cnblogs.com/jiqimin/p/10992770.html
Copyright © 2020-2023  润新知