hdu 4973 线段树
来源:互联网 发布:淘宝开店装修模板 编辑:程序博客网 时间:2024/05/01 17:40
A simple simulation problem.
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 698 Accepted Submission(s): 274
Problem Description
There are n types of cells in the lab, numbered from 1 to n. These cells are put in a queue, the i-th cell belongs to type i. Each time I can use mitogen to double the cells in the interval [l, r]. For instance, the original queue is {1 2 3 3 4 5}, after using a mitogen in the interval [2, 5] the queue will be {1 2 2 3 3 3 3 4 4 5}. After some operations this queue could become very long, and I can’t figure out maximum count of cells of same type. Could you help me?
Input
The first line contains a single integer t (1 <= t <= 20), the number of test cases.
For each case, the first line contains 2 integers (1 <= n,m<= 50000) indicating the number of cell types and the number of operations.
For the following m lines, each line represents an operation. There are only two kinds of operations: Q and D. And the format is:
“Q l r”, query the maximum number of cells of same type in the interval [l, r];
“D l r”, double the cells in the interval [l, r];
(0 <= r – l <= 10^8, 1 <= l, r <= the number of all the cells)
For each case, the first line contains 2 integers (1 <= n,m<= 50000) indicating the number of cell types and the number of operations.
For the following m lines, each line represents an operation. There are only two kinds of operations: Q and D. And the format is:
“Q l r”, query the maximum number of cells of same type in the interval [l, r];
“D l r”, double the cells in the interval [l, r];
(0 <= r – l <= 10^8, 1 <= l, r <= the number of all the cells)
Output
For each case, output the case number as shown. Then for each query "Q l r", print the maximum number of cells of same type in the interval [l, r].
Take the sample output for more details.
Take the sample output for more details.
Sample Input
15 5D 5 5Q 5 6D 2 3D 1 2Q 1 7
Sample Output
Case #1:23
Source
2014 Multi-University Training Contest 10
/*有两种操作D l r 将【l,r】区间翻倍Q l r询问[l,r]中相同数字出现的最多次数无论怎么翻倍,序列中的数都是连续的,范围是1~n。可以拿一个变量来记录每个数出现的次数,当更新或询问区间[l,r]时,可以利用其前缀和找到区间[l,r]对应的数字分别是lx,rx,对于lx+1,rx-1内的数字是完全翻倍的,可以用线段树维护区间的和以及相同数字的最大数目,由于l,r并不一定完全包含在lx.rx内,端点需要特殊处理。那么重点就是怎样找到l,r对应的数更新区间[lx,rx],可以把每个数字所在区间的左端点作为连接l,r和lx,rx的纽带,根据左端点求出右端点。*/#include<stdio.h>#define N 50005typedef long long ll;struct node{ int x,y; ll sum,mx,p;}a[N*4];ll max(ll a,ll b){ return a>b?a:b;}void pushup(int t){ int temp=t<<1; a[t].sum=a[temp].sum+a[temp+1].sum; a[t].mx=max(a[temp].mx,a[temp+1].mx);}void build(int t,int x,int y){ a[t].x=x; a[t].y=y; a[t].p=0; if(x==y) { a[t].sum=a[t].mx=1; return; } int mid=(x+y)>>1,temp=t<<1; build(temp,x,mid); build(temp+1,mid+1,y); pushup(t);}void pushdown(int t){ int temp=t<<1; if(a[t].p) { a[temp].p+=a[t].p; a[temp+1].p+=a[t].p; a[temp].sum<<=a[t].p; a[temp+1].sum<<=a[t].p; a[temp].mx<<=a[t].p; a[temp+1].mx<<=a[t].p; a[t].p=0; }}void update(ll st,ll x,ll y,int t){//st是该节点的左端点在序列中的下标,那么可知这个节点所在区间是[st,st+a[t].sum-1]。 if(st==x&&st+a[t].sum-1==y) { a[t].p++; a[t].sum*=2; a[t].mx*=2; return; } if(a[t].x==a[t].y) {//更新部分 a[t].sum+=(y-x)+1; a[t].mx=a[t].sum; return; } pushdown(t); int temp=t<<1; ll mid=st+a[temp].sum-1; if(y<=mid) update(st,x,y,temp); else if(x>mid) update(mid+1,x,y,temp+1); else { update(st,x,mid,temp); update(mid+1,mid+1,y,temp+1); } pushup(t);}ll query(ll st,ll x,ll y,int t){ ll ans; if(st==x&&y==st+a[t].sum-1) return a[t].mx; if(a[t].x==a[t].y) return (y-x+1); int temp=t<<1; pushdown(t); ll mid=st+a[temp].sum-1; if(y<=mid) ans=query(st,x,y,temp); else if(x>mid) ans=query(mid+1,x,y,temp+1); else { ll m1,m2; m1=query(st,x,mid,temp); m2=query(mid+1,mid+1,y,temp+1); ans=max(m1,m2); } pushup(t); return ans;}int main(){ int t,cnt=1,n,m; char str[10]; ll l,r; //freopen("a.txt","r",stdin); scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); build(1,1,n); printf("Case #%d:\n",cnt++); while(m--) { scanf("%s%I64d%I64d",str,&l,&r); if(str[0]=='D') update(1,l,r,1); else printf("%I64d\n",query(1,l,r,1)); } } return 0;}
0 0
- hdu 4973 线段树
- HDU - 4973(线段树+二分)
- HDU 4973 线段树 映射离散算法
- hdu 1754 线段树
- hdu 1754 线段树
- HDU 1698 线段树
- hdu 1754 线段树
- 【线段树】hdu 1754
- hdu-1166 线段树
- HDU-2688 线段树
- HDU 4027 线段树
- HDU-1166 线段树
- hdu 1166 线段树
- hdu 1754 线段树
- hdu 1754 线段树
- hdu 4027#线段树
- hdu 1754 线段树
- HDU-4351-线段树
- 他善用精良的故事来编制精确的世界观”
- bjtu1024
- 传奇的美国非虚构写作大师何伟与指导广州恒大足球队亚洲联赛夺冠的意大利教练里皮也因在各自领域的突出表现上榜。
- v4l2编程经典-转载
- OllyDbg 使用笔记 (十七)
- hdu 4973 线段树
- BZOJ 2038小Z的袜子 分块
- 2014年半年总结
- nyoj831签到
- C++实现7种基本排序
- 说说字符集和编码
- 将以何种造型亮相红毯,引人期待。
- warning LNK4042: 对象被多次指定;已忽略多余的指定
- struts2配置文件详解