[Luogu P2801] leader of the magic

Portal: https://www.luogu.org/problemnew/show/P2801

  This question is the time just to see the feeling that the two operating segments of the tree thing, maintaining a tree line just fine. However, egg and I forgot how to write a segment tree. Then think of violence hit the water through the data points, it took ten minutes to play violent, engaged in a sample. but. . . . Finally got 0 points, the same guy wrote the other giant violence got 100 points (really I was too dishes).

  Later, when the change of title glanced solution to a problem that is to use block ( already forgotten the block ), then I spent quite a long time to write a block, or submit tle a point on the Los Valley, but forget what complexity is O (msqrt (nlogn)), does not exceed the range of data (we do not know, we do not dare to ask QAQ) finally opened o2, the point is over (metaphysics). . .

#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\n",b - a + 1 - query(a,b,c));
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/jiqimin/p/10992770.html