线段树+二分
写wa了一次。。
给测试数据:
input:
1
10 100
2 9 9
1 0 1
2 5 9
1 7 11
2 5 9
1 6 0
2 5 9
2 4 9
2 6 9
1 4 4
1 5 14
2 8 9
1 5 18
2 4 9
2 1 9
1 7 3
2 6 9
2 5 9
1 6 2
1 4 0
1 7 13
2 2 9
1 7 11
1 1 1
1 5 8
2 5 9
1 2 12
2 3 9
1 0 1
2 2 9
1 9 1
2 8 9
2 5 9
2 4 9
2 0 9
1 0 5
2 6 9
2 2 9
1 7 3
1 7 15
1 1 4
1 9 7
2 8 9
2 4 9
2 9 9
1 9 3
1 4 19
1 8 15
2 8 9
2 2 9
1 8 13
1 3 17
1 3 3
2 4 9
1 6 3
2 2 9
1 5 19
2 0 9
1 8 6
2 9 9
1 9 4
1 8 0
2 1 9
1 2 15
1 9 3
1 8 2
1 3 4
2 6 9
1 0 14
1 5 19
2 5 9
1 6 10
1 6 16
2 2 9
1 2 3
1 3 6
1 1 11
1 4 18
2 5 9
1 3 19
1 4 17
2 5 9
2 7 9
1 5 16
1 2 2
1 0 14
2 0 9
1 2 3
1 7 17
1 9 2
2 7 9
1 3 2
2 2 9
1 5 4
1 6 14
2 8 9
1 3 16
2 6 9
1 5 13
1 4 3
output:
0
0 0
0
7 9
3
6 6
1
0
0
4 7
8 9
2
8 9
6
0
7 9
3
0
6 7
4 4
8 9
5
7 9
1 1
5 6
5
2 9
7
3 3
2
9 9
1
0
0
2
0 4
0
3
7 9
Can not put any one.
2 5
Can not put any one.
2
3
0
9 9
4 8
Can not put any one.
2
6
8 9
3 7
Can not put any one.
6
6 8
4
5 9
7
8 9
1
9 9
Can not put any one.
2
2 9
Can not put any one.
Can not put any one.
Can not put any one.
4
0 9
Can not put any one.
5
6 9
Can not put any one.
7
2 4
5 9
Can not put any one.
Can not put any one.
5
5 9
Can not put any one.
5
0
5 9
Can not put any one.
Can not put any one.
10
2 4
7 9
Can not put any one.
3
5 6
5
5 8
9 9
2
3 9
4
6 9
Can not put any one.
贴代码。。。懒得讲了。。。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define MAXN 100100//最大的节点数,叶子节点的两倍+100 struct node { node *left,*right;//左右子节点 int L,R;//区间的起点终点 int num;//区间内0的个数 int type;//0表示原样,1表示被置1,-1表示被置0 }treeNode[MAXN]; int nTreeNode;//初始置0,用于构造静态表结构 struct KdTree//线段树 { node *root;//树的根结点 void BuildTree(node *p,int L,int R) { p->L=L;p->R=R; p->left=NULL;p->right=NULL; p->num=p->R-p->L+1; p->type=0; if(L!=R) { int mid=((L+R)>>1); p->left=treeNode+nTreeNode++; BuildTree(p->left,L,mid); p->right=treeNode+nTreeNode++; BuildTree(p->right,mid+1,R); } } void init(int L,int R) { nTreeNode=0; root=treeNode+nTreeNode++; BuildTree(root,L,R); } void down(node *p) { p->left->type=p->type; p->right->type=p->type; if(p->type==1) p->num=0; else p->num=p->R-p->L+1; p->type=0; } int query(node *p,int L,int R)//查询[L,R]区间内0的个数 { int mid=(p->L+p->R)>>1; if(p->type==1) return 0; if(p->type==-1) return R-L+1; if(p->L==L&&p->R==R) return p->num; if(p->type!=0) down(p); if(R<=mid) { return query(p->left,L,R); } else if(L>=mid+1) { return query(p->right,L,R); } else { return query(p->left,L,mid)+query(p->right,mid+1,R); } } int truenum(node *p) { if(p->type==0) return p->num; else if(p->type==-1) return p->R-p->L+1; else return 0; } int settype(node *p,int L,int R,int type)//[L,R]区间type置1,返回[L,R]区间内0的原本个数 { if(p->L==L&&p->R==R) { int tmp=truenum(p); p->type=type; return tmp; } if(p->type!=0) down(p); int tmp=0;//记录[L,R]区间内原本的0的个数 int mid=(p->L+p->R)>>1; if(R<=mid) { tmp+=settype(p->left,L,R,type); } else if(L>=mid+1) { tmp+=settype(p->right,L,R,type); } else { tmp+=settype(p->left,L,mid,type); tmp+=settype(p->right,mid+1,R,type); } if(type==1) { p->num-=tmp; } else { p->num+=R-L+1-tmp; } return tmp; } }mytree; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int total; scanf("%d",&total); while(total--) { int n,m; scanf("%d%d",&n,&m); mytree.init(0,n-1); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a==1)//在[b,n-1]插入c个1 { //在[b,n-1]中找到第一个0 if(mytree.query(mytree.root,b,n-1)==0) {printf("Can not put any one.\n");continue;} int L=b;int R=n-1; while(L<R) { int mid=(L+R)>>1; int tmp=mytree.query(mytree.root,b,mid); if(tmp==1) R=mid; else if(tmp>1) R=mid-1; else L=mid+1; } int first=L;//[b,n]区间中第一个0的位置为first //在[first,n-1]中找到last使得query(first,last)=c int ttmp=mytree.query(mytree.root,first,n-1); if(ttmp<c) { c=ttmp; } L=first;R=n-1; while(L<R) { int mid=(L+R)>>1; int tmp=mytree.query(mytree.root,first,mid); if(tmp==c) R=mid; else if(tmp>c) R=mid-1; else L=mid+1; } int last=L; //答案为[first,last] printf("%d %d\n",first,last); mytree.settype(mytree.root,first,last,1); } else//[b,c]置0 { int zeronum=mytree.query(mytree.root,b,c); printf("%d\n",c-b+1-zeronum); mytree.settype(mytree.root,b,c,-1); } } printf("\n"); } return 0; }