关于O2的问题
  • 板块学术版
  • 楼主mmbbyy
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/9/25 21:56
  • 上次更新2024/9/26 11:55:01
查看原帖
关于O2的问题
764553
mmbbyy楼主2024/9/25 21:56

下面这段代码(P3870 [TJOI2009] 开关)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int N1=sqrt(N);//
//const int N1=320;

int n,m,a[N];
int len;
int L[N1],R[N1];
int pos[N],open[N1],tag[N1];


void change(int l,int r){
    int p=pos[l],q=pos[r];
    if(p==q){
        int cnt1=0,cnt2=0;
        for(int i=l;i<=r;i++){
            if(a[i]==0)a[i]=1,cnt1++;
            else a[i]=0,cnt2++;
        }
        if(tag[p]==0)open[p]+=cnt1-cnt2;
        else open[p]+=cnt2-cnt1;
        return;
    }
    //处理整块
    for(int i=p+1;i<=q-1;i++){
        open[i]=R[i]-L[i]+1-open[i];
        tag[i]^=1;
    }
    //处理零散块
    int cnt1=0,cnt2=0;
    for(int i=l;i<=R[p];i++){
        if(a[i]==0)a[i]=1,cnt1++;
        else a[i]=0,cnt2++;
    }
    if(tag[p]==0)open[p]+=cnt1-cnt2;
    else open[p]+=cnt2-cnt1;

    cnt1=0,cnt2=0;
    for(int i=L[q];i<=r;i++){
        if(a[i]==0)a[i]=1,cnt1++;
        else a[i]=0,cnt2++;
    }
    if(tag[q]==0)open[q]+=cnt1-cnt2;
    else open[q]+=cnt2-cnt1;
}



int query(int l,int r){
    int p=pos[l],q=pos[r];
    if(p==q){
        int ans=0;
        for(int i=l;i<=r;i++)if(a[i]==1)ans++;
        if(tag[p])return r-l+1-ans;
        else return ans;
    }
    int ans=0;
    for(int i=p+1;i<=q-1;i++)ans+=open[i];
    int cnt1=0,cnt2=0;
    for(int i=l;i<=R[p];i++)if(a[i]==1)cnt1++;
    for(int i=L[q];i<=r;i++)if(a[i]==1)cnt2++;
    if(tag[p])ans+=R[p]-l+1-cnt1;else ans+=cnt1;
    if(tag[q])ans+=r-L[q]+1-cnt2;else ans+=cnt2;
    return ans;
}

int main(){
    //printf("%d\n",N1);
    scanf("%d%d",&n,&m);
    //for(int i=1;i<=n;i++)a[i]=1;
    len=sqrt(n);
    for(int i=1;i<=len;i++){
        L[i]=(i-1)*len+1;
        R[i]=i*len;
    }
    if(R[len]!=n){
        len++;
        L[len]=R[len-1]+1;
        R[len]=n;
    }
    for(int i=1;i<=len;i++){
        for(int j=L[i];j<=R[i];j++){
            pos[j]=i;
            //open[i]=R[i]-L[i]+1;
        }
    }

    while(m--){
        int c,l,r;
        scanf("%d%d%d",&c,&l,&r);
        //printf("pos %d %d\n",pos[l],pos[r]);
        if(c==0)change(l,r);
        else printf("%d\n",query(l,r));
    }
    return 0;
}

开了O2tle成50tps,不开O2是100tps,而如果把第七行改为第八行,开O2就能过了,为什么?

2024/9/25 21:56
加载中...