看到n,m<=100000可以想到这是一个考高级数据结构的题,这个区间修改区间查询让我想到了线段树和树状数组。
然而看了一遍题后眉头一皱,发现并不简单。
它要求输出区间上炸弹种类数,那么维护区间和也不对,维护区间最大值也不对,看来不能直接套模板了。
这个时候需要重新综合考虑修改和查询的内容了。经过思考可以想到离散化的方法,把区间修改改成单点修改,区间查询即为求区间∑。
那么就可以写一个树状数组了, 毕竟代码好写很多很多很多。
对于每个修改把原数组左右端点所在位置++(注意开两个数组),经过一系列复杂的画图推演和模拟可以得到询问的ans=炸弹总数-sumzuo[r]-you[l-1];(具体推导在我英语卷上明天再来补)
本题可A。
int i,t,tl,tr; int m,n; int zuo[1000010],you[1000010]; int lowbit(int x) { return x&(-x); } void addzuo(int p,int k) { while(p<=n) { zuo[p]+=k; p+=lowbit(p); } } void addyou(int p,int k) { while(p<=n) { you[p]+=k; p+=lowbit(p); } } int sumzuo(int x) { int ans=0; while(x) { ans+=zuo[x]; x-=lowbit(x); } return ans; } int sumyou(int x) { int ans=0; while(x) { ans+=you[x]; x-=lowbit(x); } return ans; } int main() { cin>>n>>m; for(i=1;i<=m;i++) { cin>>t>>tl>>tr; if(t==1) { addzuo(tl,1); addyou(tr,1); } else cout<<sumzuo(tr)-sumyou(tl-1)<<endl; } }
还好没有卡tl=1或等0的数据…………