Color the ball
来源:互联网 发布:nba新秀数据库 编辑:程序博客网 时间:2024/06/05 19:40
N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
当N = 0,输入结束。
31 12 23 331 11 21 30
1 1 13 2 1
一、线段树
这道题,我犯了两个错
1.一直认为更新的就是1,忘记了lazy标记点的tag,可能已经是好几个1的加和,所以我们还得在设置一个变量val,来传递参数
2.就是释放标记的时候,应该释放的是树的左中,中右,自己写成了我们传递区间的左中 中右
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3fusing namespace std;typedef long long ll;const int maxn=1e5+10;struct node{ int l,r; int lazy,tag;}tree[maxn*4];void build(int st,int ed,int now_id){ tree[now_id].l=st; tree[now_id].r=ed; tree[now_id].lazy=0,tree[now_id].tag=0; if(st==ed) return; int mid=(st+ed)>>1; build(st,mid,now_id<<1); build(mid+1,ed,now_id<<1|1);}void update(int st,int ed,int now_id,int val)//前面的加和是1,可是到后面的堆积就会不是1了{ if(tree[now_id].l==st&&tree[now_id].r==ed)//如果这就是我们的区间,那我们就停在这里,把值堆在这里 { tree[now_id].lazy=1; tree[now_id].tag+=val; return;//记住写return,要不然就回不来了 } int mid=(tree[now_id].l+tree[now_id].r)>>1; if(tree[now_id].lazy) { tree[now_id].lazy=0;//记录有没有 update(tree[now_id].l,mid,now_id<<1,tree[now_id].tag);//更新的是原树 update(mid+1,tree[now_id].r,now_id<<1|1,tree[now_id].tag); tree[now_id].tag=0;//记录是多少 } if(ed<=mid) update(st,ed,now_id<<1,val); else if(st>mid) update(st,ed,now_id<<1|1,val); else update(st,mid,now_id<<1,val),update(mid+1,ed,now_id<<1|1,val);}void query(int num,int now_id){ if(tree[now_id].l==tree[now_id].r) { printf("%d",tree[now_id].tag); return; } int mid=(tree[now_id].l+tree[now_id].r)>>1; if(tree[now_id].lazy) { tree[now_id].lazy=0; update(tree[now_id].l,mid,now_id<<1,tree[now_id].tag); update(mid+1,tree[now_id].r,now_id<<1|1,tree[now_id].tag); tree[now_id].tag=0; } if(num<=mid) query(num,now_id<<1); else query(num,now_id<<1|1);}int main(){ int n; while(~scanf("%d",&n)&&n) { build(1,n,1); for(int i=1;i<=n;i++) { int a,b; scanf("%d %d",&a,&b); update(a,b,1,1);//我们上面传入的是1 } for(int i=1;i<n;i++) { query(i,1); printf(" ");//查找编号,赋值,开始编号 } query(n,1); printf("\n"); } return 0;}
二、树状数组
向下查询,向上统计
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3f#define lson(x) (x<<1)#define rson(x) (x<<1|1)#define mid_line(x,y) ((x+y)>>1)#define lowbit(x) (x&(-x))using namespace std;typedef long long ll;const int maxn=1e5+10;/*第一次用树状数组来做题,明白了一点,还是一种“复制"的思想,或者说是”等效“的思想比如说,我们2-4区间,那我们就只需要在temp[4]+1,这样的话,我们就可以当成是1-4都加上了1,但是,题目只需要2-4,,所以我们对1进行temp[1]-1,这样的话,我们的区间就控制好了查询的时候,我们就可以往上走,因为上面那个”头“,储存着我们的值,我们得把它拷贝一份,加到我们的总和上对于那些标记-1,我们只是抵消了加在他上面的1,所以他也得往上找到”头“,这样的话,才算把,自己该得的拿到手*/int temp[maxn];int n;void update(int num,int val){ while(num>0) { temp[num] += val; num -= lowbit(num); }}int getSum(int num){ int sum=0; while(num<=n) { sum += temp[num]; num += lowbit(num); } return sum;}int main(){ while(~scanf("%d",&n)&&n) { memset(temp,0,sizeof(temp)); for(int i=0;i<n;i++) { int a,b; scanf("%d %d",&a,&b); update(b,1);//因为树状数组没有办法控制区间,只能说是给个点,然后在0,处停止,或者是n处停止 update(a-1,-1);//这就是为了抵消我们上面的加1,因为我们只需要,a-b+1,不是1-b,+1,所以1-a,-1; } for(int i=1;i<n;i++) { printf("%d ",getSum(i)); } printf("%d\n",getSum(n)); } return 0;}
向上查询,向下统计
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3f#define lson(x) (x<<1)#define rson(x) (x<<1|1)#define mid_line(x,y) ((x+y)>>1)#define lowbit(x) (x&(-x))using namespace std;typedef long long ll;const int maxn=1e5+10;/*第一次用树状数组来做题,明白了一点,还是一种“复制"的思想,或者说是”等效“的思想。还有就是”死飞“,没有刹车,不是到最后,就是到最前面,对就是这样,我们只能采取补救来消除一些错误。这种向上通知,向下统计。比如说一个区间5-10,n最大是20。开头这个人就比较猖狂,直接告诉后面我们都有了,也就是5-20都+1结果,一看不对,11开始往后传,其实我们没有,所以又都会减1,这样的话,该加的加了,该减的减了。那么我们统计的时候怎么统计呢?我们就应该向下统计了,我前面有几个开头并且到我没有结束的点,不就是我被mo的次数么*/int temp[maxn];int n;void update(int num,int val){ while(num<=n) { temp[num] += val; num += lowbit(num); }}int getSum(int num){ int sum=0; while(num>0) { sum += temp[num]; num -= lowbit(num); } return sum;}int main(){ while(~scanf("%d",&n)&&n) { memset(temp,0,sizeof(temp)); for(int i=0;i<n;i++) { int a,b; scanf("%d %d",&a,&b); update(a,1);//因为树状数组没有办法控制区间,只能说是给个点,然后在0,处停止,或者是n处停止 update(b+1,-1);//这就是为了抵消我们上面的加1,因为我们只需要,a-b+1,不是1-b,+1,所以1-a,-1; } for(int i=1;i<n;i++) { printf("%d ",getSum(i)); } printf("%d\n",getSum(n)); } return 0;}
三、相同思想,直接累加前面的和
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3f#define lson(x) (x<<1)#define rson(x) (x<<1|1)#define mid_line(x,y) ((x+y)>>1)using namespace std;typedef long long ll;const int maxn=1e5+10;int temp[maxn];int main(){ int n; while(~scanf("%d",&n)&&n) { memset(temp,0,sizeof(temp)); for(int i=0;i<n;i++) { int a,b; scanf("%d %d",&a,&b); temp[a] += 1; temp[b+1] -= 1; } int s=0; for(int i=1;i<n;i++) { s += temp[i]; printf("%d ",s); } printf("%d\n",s+temp[n]); } return 0;}
阅读全文
0 0
- hdu1556 color the ball
- HDOJ Color the ball
- Color the ball
- Color the Ball
- hdu1556 Color the ball
- hdu1556 Color the ball
- hdu_1556 Color the ball
- hdu1556 Color the ball
- Color the ball----HDOJ1556
- HDU1556 Color the ball
- Color the ball
- Color the ball
- hdu1556 Color the ball
- hdu1556--Color the ball
- HDU_1556 Color the ball
- Color the ball HDU1556
- HDU1556 Color the ball
- Color the ball
- sql server实现循环功能
- activeMQ持久化mysql配置
- Android 自定义控件之自定义组合控件
- JDK1.5/1.6/1.7之新特性总结
- Eclipse快捷键
- Color the ball
- HDU
- android:Unsupported major.minor version 52.0
- 文章标题
- Rikka with Subset(HDU 6092)
- javascript实现简单计算器
- chrome hao123劫持解决
- case when用法
- maven在MANIFEST.MF文件添加参数