这两份代码区别在哪里?一份AC一份WA
  • 板块P2357 守墓人
  • 楼主cjhspeed
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/2/26 15:43
  • 上次更新2023/11/5 02:40:47
查看原帖
这两份代码区别在哪里?一份AC一份WA
238784
cjhspeed楼主2021/2/26 15:43

ac code:

#include<bits/stdc++.h>
using namespace std;

const int N=2e5+1;

typedef long long ll;

int n,f,tot=0,m,l[N],r[N],cur[N];

ll fs[N],sum[N]={0},res[N]={0};

void change(int L,int R,ll k){
	for(int i=L;i<=min(tot*cur[L],R);i++)
		fs[i]+=k,sum[cur[i]]+=k;
	
	if(cur[L]==cur[R]) return;
	
	for(int i=(cur[R]-1)*tot+1;i<=R;i++)
		fs[i]+=k,sum[cur[i]]+=k;
		
	for(int i=cur[L]+1;i<cur[R];i++)
		res[i]+=k; 
}

ll get_sum(int L,int R){
	ll ans=0;
	
	for(int i=L;i<=min(cur[L]*tot,R);i++)
		ans+=(fs[i]+res[cur[i]]);
	
	if(cur[L]==cur[R]) return ans;
	
	for(int i=(cur[R]-1)*tot+1;i<=R;i++)
		ans+=fs[i]+res[cur[i]];
				
	for(int i=cur[L]+1;i<cur[R];i++)
		ans+=sum[i]+tot*res[i]; 
	
	return ans;
}

int main(){
	scanf("%d%d",&n,&f);
	
	tot=m=sqrt(n);	
	m= m*m==n ? m : m+1;
	
	for(int i=1;i<=n;i++) {
		scanf("%lld",&fs[i]);
		cur[i]=(i-1)/tot+1;
		sum[cur[i]]+=fs[i];
	}

	while(f--){
		int op,L,R; ll k; scanf("%d",&op);
		if(op==1){
			scanf("%d%d%lld",&L,&R,&k);
			change(L,R,k);	
		} else if(op==2){
			scanf("%lld",&k);
			change(1,1,k);
		} else if(op==3){
			scanf("%lld",&k);
			change(1,1,-k);
		} else if(op==4){
			scanf("%d%d",&L,&R);
			printf("%lld\n",get_sum(L,R));
		} else printf("%lld\n",fs[1]+res[1]);
	}
	
} 

块区间首位标记是通过cur[](原序列元素所在块编号)计算出来

wa code :

#include<bits/stdc++.h>
using namespace std;

const int N=2e5+1;

typedef long long ll;

int n,f,tot=0,m,l[N],r[N],cur[N];

ll fs[N],sum[N]={0},res[N]={0};

void change(int L,int R,ll k){
	for(int i=L;i<=min(r[cur[L]],R);i++)
		fs[i]+=k,sum[cur[i]]+=k;
	
	if(cur[L]==cur[R]) return;
	
	for(int i=l[cur[R]];i<=R;i++)
		fs[i]+=k,sum[cur[i]]+=k;
		
	for(int i=cur[L]+1;i<cur[R];i++)
		res[i]+=k; 
}

ll get_sum(int L,int R){
	ll ans=0;
	
	for(int i=L;i<=min(r[cur[L]],R);i++)
		ans+=(fs[i]+res[cur[i]]);
	
	if(cur[L]==cur[R]) return ans;
	
	for(int i=l[cur[R]];i<=R;i++)
		ans+=fs[i]+res[cur[i]];
				
	for(int i=cur[L]+1;i<cur[R];i++)
		ans+=sum[i]+tot*res[i]; 
	
	return ans;
}

int main(){
	scanf("%d%d",&n,&f);
	
	tot=m=sqrt(n);	
	m= m*m==n ? m : m+1;
	
	for(int i=1;i<=n;i++) {
		scanf("%lld",&fs[i]);
		cur[i]=(i-1)/tot+1;
	} 

	for(int i=1;i<=m;i++){
		l[i]=(i-1)*tot+1,r[i]= i*tot<=n ? i*tot : n;
		for(int j=l[i];j<=r[i];j++) sum[i]+=fs[j];
	}
	

	
	while(f--){
		int op,L,R; ll k; scanf("%d",&op);
		if(op==1){
			scanf("%d%d%lld",&L,&R,&k);
			change(L,R,k);	
		} else if(op==2){
			scanf("%lld",&k);
			change(1,1,k);
		} else if(op==3){
			scanf("%lld",&k);
			change(1,1,-k);
		} else if(op==4){
			scanf("%d%d",&L,&R);
			printf("%lld\n",get_sum(L,R));
		} else printf("%lld\n",fs[1]+res[1]);
	}
	
} 

在在线之前预处理出来各个元素所在的块(cur[])与块的区间(l[],r[])

一份AC一份只有45分 ,求教为什么

2021/2/26 15:43
加载中...