hdu 3577(线段树的成段更新)

来源:互联网 发布:ui bootstrap tpls.js 编辑:程序博客网 时间:2024/06/09 17:11

这个题有一点要考虑到,就是某人从a站坐到b站,他在b站就下车了,他在车上乘坐的区间为a到b-1。

这里贡献一组测试数据

1
3 10
4 5
5 6
6 7
7 8
9 10
1 4
1 10
2 9
4 6
3 8

输出

Case 1:
1 2 3 4 5 6 7 8 


然后就是求区间最大覆盖值了。

线段树功能:updata:成段更新,query:区间最值

#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define lc l,m,index<<1#define rc m+1,r,index<<1|1#define N 1000005struct node{int add,cnt;}seg[N<<2];int q,k;void fadd(int add,int l,int r,int index){seg[index].add+=add;seg[index].cnt+=add;}void pushup(int l,int r,int index){node& father=seg[index];node& lson=seg[index<<1];node& rson=seg[index<<1|1];father.cnt=max(lson.cnt,rson.cnt);}void pushdown(int l,int r,int index){node& father=seg[index];node& lson=seg[index<<1];node& rson=seg[index<<1|1];if(father.add){int m=(l+r)>>1;fadd(father.add,lc);fadd(father.add,rc);father.add=0;}}void build(int l,int r,int index){seg[index].add=0;seg[index].cnt=0;int m=(l+r)>>1;if(l==r)return;build(lc);build(rc);}int query(int L,int R,int l,int r,int index){int m=(l+r)>>1;if(L==l&&R==r)return seg[index].cnt;pushdown(l,r,index);if(R<=m)return query(L,R,lc);else if(L>m)return query(L,R,rc);else return max(query(L,m,lc),query(m+1,R,rc));}void updata(int L,int R,int l,int r,int index){int m=(l+r)>>1;if(L==l&&R==r){fadd(1,l,r,index);return;}pushdown(l,r,index);if(R<=m)updata(L,R,lc);else if(L>m)updata(L,R,rc);else{updata(L,m,lc);updata(m+1,R,rc);}pushup(l,r,index);}int main(){//freopen("F:\\out.txt","w",stdout);int t,tcase=1,i,a,b,cnt;scanf("%d",&t);while(t--){printf("Case %d:\n",tcase++);scanf("%d%d",&k,&q);build(1,1000000,1);for(i=1;i<=q;i++){scanf("%d%d",&a,&b);b--;cnt=query(a,b,1,1000000,1);if(cnt<k){printf("%d ",i);updata(a,b,1,1000000,1);}}printf("\n\n");}return 0;}