/* 不要思维定视 盯着线段树维护l r 的ans不放 显然没法区间合并 换一种思路 如果打暴力的话 O(nm) 每次询问 扫一遍之前所有的修改 有交点则说明种数++ 接下来考虑如何优化 我们把每个区间看做(l,r)的坐标内的点 然后查询区间L<=li<=R L<=ri<=R内有多少点 这样的查询在二维坐标里不会查(反正我不会..)将坐标轴转化成两个一维的线段 这样我们就又面临一个问题 会有重复 那就用排除法 总数-不重复区间的 又因为保证了 r>=l 所以l轴的[r+1,n] +r 轴的[1,l-1] 恰好不重复且覆盖了所有多出来的点 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 100010 using namespace std; int n,m,tl[maxn],tr[maxn],sum; void Add_treel(int pos,int data) { while(pos<=n) { tl[pos]+=data; pos+=pos&(-pos); } } void Add_treer(int pos,int data) { while(pos<=n) { tr[pos]+=data; pos+=pos&(-pos); } } int find_treel(int pos) { int ret=0; while(pos) { ret+=tl[pos]; pos-=pos&(-pos); } return ret; } int find_treer(int pos) { int ret=0; while(pos) { ret+=tr[pos]; pos-=pos&(-pos); } return ret; } int main() { freopen("greedisland.in","r",stdin); freopen("greedisland.out","w",stdout); scanf("%d%d",&n,&m); int x,y,z; for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); if(x==1){Add_treel(y,1);Add_treer(z,1);sum++;} if(x==2) { int s1=find_treel(n)-find_treel(z); int s2=find_treer(y-1); printf("%d\n",sum-s1-s2); } } return 0; }
时间: 2024-10-02 22:49:40