求大佬帮我优化一下常数

P2801 教主的魔法

qianfujia @ 2018-03-18 21:46:03

#include<bits/stdc++.h>
#define ll long long
#define N 1000010
#define S 1010
using namespace std;
int n, m;
int Belong[N];
int Square[N];
int Tag[S];
int L[S];
int R[S];
int sum;
int A[N];
inline void build()
{
    sum = sqrt(n);
    int size = n / sum;
    if(n % sum)
        ++ sum;
    for(int i = 1; i < sum; ++ i)
    {
        L[i] = R[i - 1] + 1;
        R[i] = L[i] + size - 1;
        for(int j = L[i]; j <= R[i]; ++ j)
            Square[j] = A[j], Belong[j] = i;
        sort(Square + L[i], Square + R[i] + 1);
    }
    L[sum] = R[sum - 1] + 1;
    R[sum] = n;
    for(int i = L[sum]; i <= n; ++ i)
        Square[i] = A[i], Belong[i] = sum;
    sort(Square + L[sum], Square + R[sum] + 1);
}
inline void Change(int l, int r, int W)
{
    int xl = Belong[l], xr = Belong[r];
    if(xl == xr)
    {
        for(int i = l; i <= r; ++ i)
            A[i] += W;
        for(int i = L[xl]; i <= R[xl]; ++ i)
            Square[i] = A[i];
        sort(Square + L[xl], Square + R[xl] + 1);
        return;
    }
    for(int i = l; i <= R[xl]; ++ i)
        A[i] += W;
    for(int i = L[xl]; i <= R[xl]; ++ i)
        Square[i] = A[i];
    sort(Square + L[xl], Square + R[xl] + 1);
    for(int i = L[xr]; i <= r; ++ i)
        A[i] += W;
    for(int i = L[xr]; i <= R[xr]; ++ i)
        Square[i] = A[i];
    sort(Square + L[xr], Square + R[xr] + 1);
    for(int i = xl + 1; i < xr; ++ i)
        Tag[i] += W;
}
inline int Query(int l, int r, int C)
{
    int xl = Belong[l], xr = Belong[r];
    if(xl == xr)
    {
        int cnt = 0;
        for(int i = l; i <= r; ++ i)
            if(A[i] + Tag[xl] >= C)
                ++ cnt;
        return cnt;
    }
    int cnt = 0;
    for(int i = l; i <= R[xl]; ++ i)
        if(A[i] + Tag[xl] >= C)
            ++ cnt;
    for(int i = L[xr]; i <= r; ++ i)
        if(A[i] + Tag[xr] >= C)
            ++ cnt;
    for(int i = xl + 1; i < xr; ++ i)
    {
        int left = L[i], right = R[i];
        while(left < right)
        {
            int mid = (left + right) >> 1;
            if(Square[mid] + Tag[i] >= C)
                right = mid;
            else
                left = mid - 1;
        }
        cnt += R[i] - left + 1;
    }
    return cnt;
}
inline void read(int &x)
{
    x = 0;
    char ch = getchar();
    while(ch < '0' || ch > '9')
        ch = getchar();
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + (ch ^ 48);
        ch = getchar();
    }
}
int main()
{
    read(n), read(m);
    for(int i = 1; i <= n; ++ i)
        read(A[i]);
    while(m --)
    {
        char s[2];
        int x, y, z;
        scanf("%s%d%d%d", s, &x, &y, &z);
        if(s[0] == 'M')
            Change(x, y, z);
        else
            printf("%d\n", Query(x, y, z));
    }
    return 0;
}

by Anguei @ 2018-03-19 00:03:27

@dijstra 写了 read 为什么用 scanf?


|