Vases and Flowers HDU
来源:互联网 发布:excel怎么剔除重复数据 编辑:程序博客网 时间:2024/05/20 06:08
Alice有N个花瓶(标号为0~ N-1)。当她收到一些花时,她会随机的选择一个瓶子A,从它开始遍历A,A+1, A+2, ..., N-1号瓶子,遇到空瓶子就放一朵花进去,直到花朵放完或没有瓶子,剩下的花将被丢弃。有时,她也会清理标号从A到B的花瓶(A <= B).花瓶里的花会被丢弃。
Input Output Sample Input Sample Output 里面有类似这样的查找机制,直接套用了。
第一行一个整数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).
对于每个K=1的操作,输出第一朵和最后一朵花放置的花瓶标号。如果没有任何放花的位置,输出'Can not put any one.'.对于K=2的操作,输出丢弃花的个数.
每组数据后输出一个空行.
210 51 3 52 4 51 1 82 3 61 8 810 61 2 52 3 41 0 82 2 51 4 41 2 3
3 721 94Can not put any one.2 620 944 52 3刚拿到这道题又是很懵。然后仔细想了一下,发现不是很难。当2操作的时候,要显示更改的次数,说明线段树肯定是要存储区间和的。存储什么和呢?
仔细想一下你会发现,还是储存没有被占用的点的个数合适。这样就可以求出区间的操作1的l和r。因为你知道任何一个区间的未占用的个数
那么就可以用二分来求出第一个未占用的点在哪里,同理,可以求出最后一个点在哪里。再用线段树更新更新l,r。这里最大的难度可能就是二分查找了,还好昨天做过cf,
下面给出代码
#include<bits/stdc++.h>using namespace std;const int M=5e4+10;int lazy[4*M],tree[4*M],n;void creat(int now,int l,int r){ lazy[now]=-1; if(l==r) { tree[now]=1;//叶子节点一个0 return ; } int mid=(l+r)/2; creat(now*2+1,l,mid); creat(now*2+2,mid+1,r); tree[now]=tree[now*2+1]+tree[now*2+2];}void pushdown(int now,int l,int r){ if(lazy[now]!=-1) { int mid=(l+r)/2; lazy[now*2+1]=lazy[now*2+2]=lazy[now]; lazy[now]=-1; tree[now*2+1]=lazy[now*2+1]*(mid-l+1); tree[now*2+2]=lazy[now*2+2]*(r-mid); }}int query(int now,int l,int r,int al,int ar){ int mid=(l+r)/2; if(al>r||ar<l) return 0; if(al<=l&&ar>=r) return tree[now]; pushdown(now,l,r); return query(now*2+1,l,mid,al,ar)+query(now*2+2,mid+1,r,al,ar);}void update(int now,int l,int r,int al,int ar,int val){ int mid=(l+r)/2; if(al>r||ar<l) return ; if(al<=l&&ar>=r) { lazy[now]=val; tree[now]=val*(r-l+1); return ; } pushdown(now,l,r); update(now*2+1,l,mid,al,ar,val); update(now*2+2,mid+1,r,al,ar,val); tree[now]=tree[now*2+1]+tree[now*2+2];}int find1(int l,int r){ int ans; while(l<=r) { int mid=(l+r)/2; int sum=query(0,0,n-1,l,mid); if(sum>0)//存在没有插的位置 { ans=mid; r=mid-1; } else { l=mid+1; } } return ans;}int find2(int l,int r,int remind){ int ans; int k=l; while(l<=r) { int mid=(l+r)/2; int sum=query(0,0,n-1,k,mid); if(sum>=remind) { ans=mid; r=mid-1; } else { l=mid+1; } } return ans;}int main(){ int t,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); creat(0,0,n-1); while(m--) { int op,a,b; scanf("%d%d%d",&op,&a,&b); if(op==1) { int have=query(0,0,n-1,a,n-1); if(!have) { printf("Can not put any one.\n"); continue; } int left=find1(a,n-1); int right=find2(a,n-1,min(have,b)); update(0,0,n-1,left,right,0); printf("%d %d\n",left,right); } else { int have1=query(0,0,n-1,a,b); update(0,0,n-1,a,b,1); int have2=query(0,0,n-1,a,b); printf("%d\n",have2-have1); } } putchar('\n'); }}
阅读全文
0 0
- Vases and Flowers HDU
- Vases and Flowers HDU
- Vases and Flowers HDU
- hdu 4614 Vases and Flowers
- hdu 4614 Vases and Flowers
- HDU 4614 Vases and Flowers
- hdu 4614 Vases and Flowers
- hdu 4614 Vases and Flowers
- HDU-4614-Vases and Flowers
- HDU 4614 Vases and Flowers
- HDU 4614 Vases and Flowers
- HDU 4614 Vases and Flowers
- HDU 4614 Vases and Flowers
- HDU 4614 Vases and Flowers 解题报告
- hdu 4614 Vases and Flowers 线段树
- HDU 4614(Vases and Flowers)
- hdu 4614——Vases and Flowers
- hdu 4614 Vases and Flowers 线段树
- C语言学习:简单了解下stdlib中的字符串转换函数
- hdu5352城市重建 (km,最大流,费用流)
- [BZOJ2238]填表格
- 特征选取relief算法
- Nginx系列—location总结及rewrite规则写法
- Vases and Flowers HDU
- AlarmManager实现闹钟
- java集合TreeMap使用自然排序,定制排序
- 最大子段和的拓展
- 分数化小数 (decimal) 算法竞赛入门经典 第二版 习题 2-5
- 分拆素数和
- 谭爷的黑暗沙拉 UESTC
- 面向对象之继承
- 2017.7.23 学习日记