#include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #define inf 0x3f3f3f3f #define LL unsigned long long #define left_child now<<1,l,mid #define right_child now<<1|1,mid+1,r using namespace std; int n,q; struct node{ int l,r; long long tot; bool lazy; }e[100010*4]; int map[100010*3],map2[100010*3],Hashhash[100010*3]; int k=1; int a,b,c,m; int op[100010]; int Left[100010]; int Right[100010]; int f(int u) { int now=0; now = lower_bound(map + 1,map + 1 + m,u) - map; return now; } void build(int now,int l,int r) { e[now].l=l,e[now].r=r; if(l==r)return; int mid=(l+r)>>1; build(left_child); build(right_child); } void pushdown(int k) { e[k<<1].tot = map[e[k<<1].r]-map[e[k<<1].l-1]; e[k<<1].lazy=1; e[k<<1|1].tot = map[e[k<<1|1].r]-map[e[k<<1|1].l-1]; e[k<<1|1].lazy=1; e[k].lazy=0; } void update(int now,int l,int r,int x,int y) { if(map[x-1]+1<=map[l-1]+1&&map[r]<=map[y]) // if(x<=l&&r<=y) { e[now].tot=map[r]-map[l-1]; e[now].lazy=1; return ; } // if(e[now].lazy==1)pushdown(now); if(e[now].lazy==1)return ; int mid=(l+r)>>1; if(y<=mid) { update(now<<1,l,mid,x,y); } else if(x>mid) { update(now<<1|1,mid+1,r,x,y); } else { update(now<<1,l,mid,x,y); update(now<<1|1,mid+1,r,x,y); } e[now].tot=e[now<<1].tot+e[now<<1|1].tot; } int query(int now,int l,int r,int x,int y) { if(map[x-1]+1<=map[l-1]+1&&map[r]<=map[y]) // if(x<=l&&r<=y) { return e[now].tot; } int mid=(l+r)>>1; if(e[now].lazy==1)return min(map[r],map[y])-max(map[l-1]+1,map[x-1]+1)+1; // if(e[now].lazy==1)pushdown(now); if(y<=mid)return query(now<<1,l,mid,x,y); else if(x>mid)return query(now<<1|1,mid+1,r,x,y); else { return query(now<<1,l,mid,x,mid)+query(now<<1|1,mid+1,r,mid+1,y); } } int main() { scanf("%d%d",&n,&q); for(int i=1;i<=q;i++) { scanf("%d%d%d",&a,&b,&c); op[i]=a; Left[i]=b; Right[i]=c; map[k++]=b-1; map[k++]=c; } for(int i=1;i<=2*q;i++)map2[i]=map[i]; sort(map+1,map+k); m= unique(map+1,map+k)-map-1;//去重后有M个 for(int i = 1;i <= m;++i)Hashhash[i] = i; build(1,1,m); map[0]=0; for(int i=1;i<=q;i++) { if(op[i]==1) { update(1,1,m,f(Left[i]),f(Right[i])); // update(1,1,m,Left[i],Right[i]); } else { printf("%d\n",Right[i]-Left[i]+1-query(1,1,m,f(Left[i]),f(Right[i]))); // printf("%d\n",Right[i]-Left[i]+1-query(1,1,m,Left[i],Right[i])); } } return 0; }
自己的代码。
另贴一大神的代码。
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #include<cstdlib> #include<vector> using namespace std; int n,q; struct Q { int op,l,r; }ques[100000+10]; vector<int>stable; int m; struct T { int l,r; int sum; bool flag;//这道题的特殊性质,可以不用标准的lazy处理方法 }tree[100000*8+10]; void build(int id,int l,int r) { tree[id].l=l;tree[id].r=r;tree[id].flag=0; if(l==r)return; int mid=l+r>>1; build(id<<1,l,mid); build(id<<1|1,mid+1,r); } void update(int id,int l,int r) { if(l<=stable[tree[id].l-1]+1&&stable[tree[id].r]<=r) { tree[id].flag=true;tree[id].sum=stable[tree[id].r]-stable[tree[id].l-1]; return; } if(tree[id].flag)return; int mid=tree[id].l+tree[id].r>>1; if(l<=stable[mid])update(id<<1,l,r); if(r>stable[mid])update(id<<1|1,l,r); tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum; } int query(int id,int l,int r) { if(l<=stable[tree[id].l-1]+1&&stable[tree[id].r]<=r) { // cerr<<stable[tree[id].l-1]+1<<" "<<stable[tree[id].r]<<endl; return tree[id].sum; } if(tree[id].flag) { return min(r,stable[tree[id].r])-max(l,stable[tree[id].l-1]+1)+1; } int ret=0; int mid=tree[id].l+tree[id].r>>1; if(l<=stable[mid])ret+=query(id<<1,l,r); if(r>stable[mid])ret+=query(id<<1|1,l,r); return ret; } int main() { scanf("%d%d",&n,&q); for(int i=1;i<=q;i++) { scanf("%d%d%d",&ques[i].op,&ques[i].l,&ques[i].r); stable.push_back(ques[i].l-1); stable.push_back(ques[i].r); } //stable.push_back(0); sort(stable.begin(),stable.end()); stable.erase(unique(stable.begin(),stable.end()),stable.end()); m=stable.size()-1; // for(int i=1;i<=m;i++)printf(" %d",stable[i]);printf("\n"); build(1,1,m); for(int i=1;i<=q;i++) { if(ques[i].op==1)update(1,ques[i].l,ques[i].r); else printf("%d\n",ques[i].r-ques[i].l+1-query(1,ques[i].l,ques[i].r)); } return 0; }