HDU 4614 花瓶与花
Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
Alice有N个花瓶(标号为0~
N-1)。当她收到一些花时,她会随机的选择一个瓶子A,从它开始遍历A,A+1, A+2, ..., N-1号瓶子,遇到空瓶子就放一朵花进去,直到花朵放完或没有瓶子,剩下的花将被丢弃。有时,她也会清理标号从A到B的花瓶(A <= B).花瓶里的花会被丢弃。
Input
第一行一个整数T,表示数据组数。
每组数据,第一行一个整数N(1 < N < 50001) and M(1 < M < 50001). N 是花瓶个数, M 是Alice的操作次数. 接下来M行 行3个 整数. 第一个整数 K(1 or 2). 如果K=1, 后面跟两个整数 A 和 F . 表示Alice 得到了F 朵花并且把它们放入从A 的花瓶里. 如果K= 2, 后跟两个整数 A 和 B. 表示Alice 清理的花瓶标号范围(A <= B).
Output
对于每个K=1的操作,输出第一朵和最后一朵花放置的花瓶标号。如果没有任何放花的位置,输出'Can not put any one.'.对于K=2的操作,输出丢弃花的个数.
每组数据后输出一个空行.
Sample Input
2 10 5 1 3 5 2 4 5 1 1 8 2 3 6 1 8 8 10 6 1 2 5 2 3 4 1 0 8 2 2 5 1 4 4 1 2 3
Sample Output
3 7 2 1 9 4 Can not put any one. 2 6 2 0 9 4 4 5 2 3 解题思路: 一看就知道是线段树的题目,刚开始不敢做嫌麻烦,但是一旦做起来感觉这个题目思路还是非常的直接的 1,几个主要操作,寻找位置,区间赋值,求和 2,维护这几个数据就可以了,寻找位置和求和分开写了两个query 3,关于找位置的写法是非常常用的一定要非常的熟练。#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn = 50005 ; int sum[maxn<<2] ; int setv[maxn<<2] ; void pushdown(int l,int r,int rt){ int m = (l+r)>>1 ; if(setv[rt]!=-1){ setv[rt<<1] = setv[rt] ; setv[rt<<1|1] = setv[rt] ; sum[rt<<1] = setv[rt]*(m-l+1) ; sum[rt<<1|1] = setv[rt]*(r-m) ; setv[rt] = -1 ; } } void pushup(int rt){ sum[rt] = sum[rt<<1]+sum[rt<<1|1] ; } void build(int l,int r,int rt){ if(l==r){ sum[rt] = 1 ; return ; } int m = (l+r)>>1 ; build(lson) ; build(rson) ; pushup(rt) ; } void update(int L,int R,int s,int l,int r,int rt){ if(L<=l&&r<=R){ setv[rt] = s ; sum[rt] = s*(r-l+1) ; return ; } int m = (l+r)>>1; pushdown(l,r,rt) ; if(L<=m)update(L,R,s,lson) ; if(R>m)update(L,R,s,rson) ; pushup(rt) ; } int query(int L,int R,int l,int r,int rt){ int ret = 0 ; if(L<=l&&r<=R)return sum[rt] ; pushdown(l,r,rt) ; int m = (l+r)>>1; if(L<=m)ret+=query(L,R,lson) ; if(R>m)ret+=query(L,R,rson) ; return ret ; } int query2(int p,int l,int r,int rt){ if(l==r)return l ; pushdown(l,r,rt); int m = (l+r)>>1 ; if(p>sum[rt<<1]){ query2(p-sum[rt<<1],rson) ; } else query2(p,lson) ; } int main(){ int T; int n,m; //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--){ memset(sum,0,sizeof(sum)); memset(setv,-1,sizeof(setv)); scanf("%d%d",&n,&m); build(1,n,1) ; for(int i=0;i<m;i++){ int op = 0 ; scanf("%d",&op); if(op==1){ int a,f; scanf("%d%d",&a,&f); a++ ; int num ; if(a==1)num=0; else num = query(1,a-1,1,n,1) ; if(sum[1]-num>0){ int index1 = query2(num+1,1,n,1) ; int index2 = query2(min(num+f,sum[1]),1,n,1) ; printf("%d %d\n",index1-1,index2-1); update(index1,index2,0,1,n,1) ; }else printf("Can not put any one.\n"); }else{ int a,b; scanf("%d%d",&a,&b); a++;b++; int ans = query(a,b,1,n,1) ; ans = b-a+1-ans ; printf("%d\n",ans); update(a,b,1,1,n,1) ; } } printf("\n"); } return 0; }