本人在写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 了,问是什么回事?