题意:
一共有两种操作
1. 给区间 L R 每个位置加上一种 标记
2.询问区间 L R 一共有多少种标记
之前做到过一种简易版的 (区间染色count color)(标记只有三十种 ) 所以可以用位运算模拟
还有一个差别就是那种会覆盖掉 这种是无限累加
显然表示某个区间的状态是很难实现的
对每个操作1 可以插入两个点表示头和尾
答案为 1-R 的头标记数 减去 1-(L-1)的尾标记数!!!
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f #define lson l,m,pos<<1 #define rson m+1,r,pos<<1|1 const int N=1e5+5; int head[N<<2],tail[N<<2]; int sumhead[N<<2],sumtail[N<<2]; void up(int pos) { head[pos]=head[pos<<1]+head[pos<<1|1]; tail[pos]=tail[pos<<1]+tail[pos<<1|1]; } void update(int x,int flag,int l,int r,int pos) { if(l==r) { if(flag==1)head[pos]++; else tail[pos]++; return ; } int m=(l+r)>>1; if(x<=m)update(x,flag,lson); else update(x,flag,rson); up(pos); } int query(int L,int R,int flag,int l,int r,int pos) { if(L<=l&&r<=R) { if(flag==1)return head[pos]; else if(flag==2)return tail[pos]; } int ans=0; int m=(l+r)>>1; if(L<=m)ans+=query(L,R,flag,lson); if(R>m)ans+=query(L,R,flag,rson); up(pos); return ans; } int n,m,a,b,c; int main() { RII(n,m); while(m--) { RIII(a,b,c); if(a==1){update(b,1,1,n,1);update(c,2,1,n,1);} else cout<<query(1,c,1,1,n,1)-query(1,b-1,2,1,n,1)<<endl; } return 0; }