关于神奇现象
查看原帖
关于神奇现象
609565
OtterZ楼主2023/10/20 19:49

本人在写ODT时,决定将两端同色线段合并,以优化程序:

#include<cstdio>
#include<set>
#include<bitset>
#include<vector>
#define int long long//怀疑编译器神评 
using namespace std;
struct line{//线段 
	int l,r;
	mutable int v;
	line(int _l=0,int _r=0,int _v=0){
		l=_l;
		r=_r;
		v=_v;
	}
	bool operator<(const line &b)const{//维护线段顺序
		return l<b.l; 
	}
};
set<line>ODT;//珂朵莉树
//typedef ODTZZ set<line>::iterator;//清晰明了
set<line>::iterator split(int l){//分裂 
	set<line>::iterator it=ODT.lower_bound(line(l));
	if(it!=ODT.end()&&it->l==l)return it;//风水好,不必画蛇添足
	it--;
	int lf=it->l,rt=it->r,val=it->v;//备份
	ODT.erase(it);//腾出空间;
	ODT.insert(line(lf,l-1,val));
	return ODT.insert(line(l,rt,val)).first;
} 
void A(int V,int L){//A操作 
	set<line>::iterator itr=split(L+1),itl=split(L);
	itl->v+=V;
	int l=L,r=L,val=itl->v;
	if(itr!=ODT.end()&&itl->v==itr->v){
		r=itr->r;
		ODT.erase(itr);//合并 
	}
	if(itl!=ODT.begin()){
		itr=itl;
		itr--;
		if(itr->v==itl->v){
			l=itr->l;
			ODT.erase(itr);
		}
	}
	ODT.erase(itl);
	ODT.insert(line(l,r,val));
}
void R(int a,int l,int r){
	set<line>::iterator itr=split(r+1),itl=split(l);
	if(itr!=ODT.end()&&itr->v==a){
		r=itr->r;
		itr++;
	}
	if(itl!=ODT.begin()){
		set<line>::iterator its=itl;
		its--;
		if(its->v==a){
			l=its->l;
			itl=its;
		}
	}
	ODT.erase(itl,itr);
	ODT.insert(line(l,r,a));
}
int ss[10000009],cnt;
bitset<10000009>isntp;
void initp(){//初始化 
	isntp[0]=isntp[1]=true;
	for(int i=2;i<=10000000;i++){
		//printf("%d ",isntp[i]?1:0);
		if(!isntp[i]){
			ss[++cnt]=i;
		}
		for(int j=1;j<=cnt&&i*ss[j]<=10000000;j++){
			isntp[i*ss[j]]=true;
		}
	}
}
int Q(int l,int r){
	set<line>::iterator itr=split(r+1),itl=split(l);
	int ret=0;
	for(set<line>::iterator it=itl;it!=itr;it++){
		if(it->v<=10000000&&!isntp[it->v]){
			ret+=it->r-it->l+1;
		}
	}
	//合并同取值区间,加快代码 
	set<line>::iterator its=ODT.end();
	if(itr!=ODT.end()){
		its=itr;
		its--;
		if(its->v==itr->v){
			int lf=its->l,rt=itr->r,val=itr->v;
			ODT.erase(itr);
			ODT.erase(its);
			ODT.insert(line(lf,rt,val));
		}
	}
	if(itl!=ODT.begin()){
		its=itl;
		its--;
		if(its->v==itl->v){
			int lf=its->l,rt=itl->r,val=itl->v;
			ODT.erase(itl);
			ODT.erase(its);
			ODT.insert(line(lf,rt,val));
		}
	}
	return ret;
}
int n,m,a,la,l,r;
char c;
signed main(){
	scanf("%lld%lld",&n,&m);
	ODT.insert(line(1,n+1,0x3f3f3f3f));
	initp();
	for(int i=1;i<=n;i++){
		scanf("%lld",&a);
		R(a,i,i);
	}
	for(int i=1;i<=m;i++){
		scanf(" %c",&c);
		scanf("%lld%lld",&l,&r);
		if(c=='A'){
			A(l,r);
		}
		else if(c=='Q'){
			printf("%lld\n",Q(l,r));
		}
		else if(c=='R'){
			scanf("%lld",&a);
			R(l,r,a);
		}
	}
	return 0;
}

结果神奇re 把对应优化注释掉,得到如下代码:

#include<cstdio>
#include<set>
#include<bitset>
#include<vector>
#define int long long//怀疑编译器神评 
using namespace std;
struct line{//线段 
	int l,r;
	mutable int v;
	line(int _l=0,int _r=0,int _v=0){
		l=_l;
		r=_r;
		v=_v;
	}
	bool operator<(const line &b)const{//维护线段顺序
		return l<b.l; 
	}
};
set<line>ODT;//珂朵莉树
//typedef ODTZZ set<line>::iterator;//清晰明了
set<line>::iterator split(int l){//分裂 
	set<line>::iterator it=ODT.lower_bound(line(l));
	if(it!=ODT.end()&&it->l==l)return it;//风水好,不必画蛇添足
	it--;
	int lf=it->l,rt=it->r,val=it->v;//备份
	ODT.erase(it);//腾出空间;
	ODT.insert(line(lf,l-1,val));
	return ODT.insert(line(l,rt,val)).first;
} 
void A(int V,int L){//A操作 
	set<line>::iterator itr=split(L+1),itl=split(L);
	itl->v+=V;
	/*int l=L,r=L,val=itl->v;
	if(itr!=ODT.end()&&itl->v==itr->v){
		r=itr->r;
		ODT.erase(itr);//合并 
	}
	if(itl!=ODT.begin()){
		itr=itl;
		itr--;
		if(itr->v==itl->v){
			l=itr->l;
			ODT.erase(itr);
		}
	}
	ODT.erase(itl);
	ODT.insert(line(l,r,val));*/
}
void R(int a,int l,int r){
	set<line>::iterator itr=split(r+1),itl=split(l);
	/*if(itr!=ODT.end()&&itr->v==a){
		r=itr->r;
		itr++;
	}
	if(itl!=ODT.begin()){
		set<line>::iterator its=itl;
		its--;
		if(its->v==a){
			l=its->l;
			itl=its;
		}
	}*/
	ODT.erase(itl,itr);
	ODT.insert(line(l,r,a));
}
int ss[10000009],cnt;
bitset<10000009>isntp;
void initp(){//初始化 
	isntp[0]=isntp[1]=true;
	for(int i=2;i<=10000000;i++){
		//printf("%d ",isntp[i]?1:0);
		if(!isntp[i]){
			ss[++cnt]=i;
		}
		for(int j=1;j<=cnt&&i*ss[j]<=10000000;j++){
			isntp[i*ss[j]]=true;
		}
	}
}
int Q(int l,int r){
	set<line>::iterator itr=split(r+1),itl=split(l);
	int ret=0;
	for(set<line>::iterator it=itl;it!=itr;it++){
		if(it->v<=10000000&&!isntp[it->v]){
			ret+=it->r-it->l+1;
		}
	}
	/*//合并同取值区间,加快代码 
	set<line>::iterator its=ODT.end();
	if(itr!=ODT.end()){
		its=itr;
		its--;
		if(its->v==itr->v){
			int lf=its->l,rt=itr->r,val=itr->v;
			ODT.erase(itr);
			ODT.erase(its);
			ODT.insert(line(lf,rt,val));
		}
	}
	if(itl!=ODT.begin()){
		its=itl;
		its--;
		if(its->v==itl->v){
			int lf=its->l,rt=itl->r,val=itl->v;
			ODT.erase(itl);
			ODT.erase(its);
			ODT.insert(line(lf,rt,val));
		}
	}*/
	return ret;
}
int n,m,a,la,l,r;
char c;
signed main(){
	scanf("%lld%lld",&n,&m);
	ODT.insert(line(1,n+1,0x3f3f3f3f));
	initp();
	for(int i=1;i<=n;i++){
		scanf("%lld",&a);
		R(a,i,i);
	}
	for(int i=1;i<=m;i++){
		scanf(" %c",&c);
		scanf("%lld%lld",&l,&r);
		if(c=='A'){
			A(l,r);
		}
		else if(c=='Q'){
			printf("%lld\n",Q(l,r));
		}
		else if(c=='R'){
			scanf("%lld",&a);
			R(l,r,a);
		}
	}
	return 0;
}

反而 A 了,问是什么回事?

2023/10/20 19:49
加载中...