关于分块大小、数组大小以及O2的玄学问题

P2801 教主的魔法

ouuan @ 2018-09-29 13:45:45

AC代码见下方。

N为数组大小,B为分块大小(具体见代码)

N B O2 结果
1001010 998 AC
1001010 998 AC
1000010 998 WA80
1000010 998 AC
1001010 1000 WA80
1001010 1000 WA80

为什么会出现这种玄学现象...是我哪里写炸了吗?

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

inline int read()
{
    char c;int out=0;
    for (c=getchar();c<'0'||c>'9';c=getchar());
    for (;c>='0'&&c<='9';c=getchar()){out=(out<<3)+(out<<1)+c-'0';}
    return out;
}
void write(int x)
{
    if (x>9){write(x/10);}
    putchar(x%10+'0');
}

const int B=998;
const int N=1001010;

bool cmp(int x,int y);
void bf(int l,int r,int x);
int bq(int l,int r,int x);

int n,q,a[N],b[N],tag[N/B+10],bl[N],ll[N/B+10],rr[N/B+10];
char wtf[10];

int main()
{
    int i,l,r,x,ans;

    n=read();
    q=read();

    for (i=1;i<=n;++i)
    {
        cin>>a[i];
        b[i]=i;
        bl[i]=(i-1)/B+1;
    }

    for (i=1;i<=bl[n];++i)
    {
        ll[i]=i*B-B+1;
        rr[i]=i*B;
        sort(b+ll[i],b+rr[i]+1,cmp);
    }

    rr[bl[n]]=n;

    while (q--)
    {
        scanf("%s",wtf);
        l=read();
        r=read();
        x=read();
        if (wtf[0]=='M')
        {
            if (bl[l]==bl[r])
            {
                bf(l,r,x);
            }
            else
            {
                bf(l,rr[bl[l]],x);
                bf(ll[bl[r]],r,x);
                for (i=bl[l]+1;i<bl[r];++i)
                {
                    tag[i]+=x;
                }
            }
        }
        else
        {
            if (l/B==r/B)
            {
                cout<<bq(l,r,x)<<endl;
            }
            else
            {
                ans=bq(l,rr[bl[l]],x)+bq(ll[bl[r]],r,x);
                for (i=bl[l]+1;i<bl[r];++i)
                {
                    a[N-1]=x-tag[i];
                    ans+=upper_bound(b+ll[i],b+rr[i]+1,N-1,cmp)-b-ll[i];
                }
                cout<<ans<<endl;
            }
        }
    }

    return 0;
}

bool cmp(int x,int y)
{
    return a[x]>a[y];
}

void bf(int l,int r,int x)
{
    for (int i=l;i<=r;++i)
    {
        a[i]+=x;
    }
    sort(b+ll[bl[l]],b+rr[bl[l]]+1,cmp);
}

int bq(int l,int r,int x)
{
    int i,out=0;
    for (i=l;i<=r;++i)
    {
        out+=(a[i]>=x);
    }
    return out;
}

by 夜刀神十香ღ @ 2018-09-29 13:48:44

反正Orz就对了


by ouuan @ 2018-09-29 13:49:19

突然发现我提交了2页半..


by FC是女孩子 @ 2018-09-29 13:50:39

反正Orz就对了


by 星小雨 @ 2018-09-29 13:50:52

这只是数组开小了。。吧


by ouuan @ 2018-09-29 13:53:05

@星小雨 为什么会数组开小呢(我哪里写炸了?按理来说1000010应该不会开小)..为什么开小了不开O2能A呢..为什么开小了开O2不会RE呢..(一般情况下数组越界不开O2WA开O2RE)


by Devil_Wings @ 2018-09-29 13:54:41

反正Orz就对了


by x_angelkawaii_x @ 2018-09-29 13:57:40

@ouuan
O2好像对某些越界情况要求更为严格吧...


by info___tion @ 2018-09-29 14:02:52

@ouuan 您这段代码没有用什么STL啊,(据本人经验)在没有用STL的情况下开O_2会跑得更慢的


by ouuan @ 2018-09-29 14:07:50

@info___tion 没有STL应该也不会更慢吧..而且我用了upper_bound,事实上O2确实快一些(2.1s→0.9s)


by ouuan @ 2018-09-29 14:09:16

@沉迷学习的YSJ 所以说我有哪越界了吗...而且正是因为O2严格一些越界应该会RE的,然而WA了


| 下一页