zoj 3597 Hit the Target! (线段树)
来源:互联网 发布:阿里云认证 有用吗 编辑:程序博客网 时间:2024/06/16 19:20
题意:有n个枪和m个靶子,每个枪只有一颗子弹,给出枪能达到的靶子,现在有同等的概率的选择连续p个枪,然后选择连续q个靶子,使得能获得的分数最大,问最后获得分数的期望。
思路:可以枚举一下选择连续p个枪的区间,然后维护能够打到的靶子的最大数量,就能解决这个问题了。用线段树保存用当前的枪能打到的,以x为右端点,左边连续q个靶子的分数总和,那么对于每枝枪,更新区间[y,min(y+q-1,m))]即可。由于同一枝枪有可能可以打多个靶子,但是只有一发子弹,因此,更新这个区间的时候不能不能相互覆盖,这里排下序就可以解决了。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=500000+10;vector<pair<int,int> >shot[maxn];int maxv[maxn<<2],addv[maxn<<2];inline void PushUp(int rt){ maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);}inline void PushDown(int rt){ if(addv[rt]) { addv[rt<<1]+=addv[rt]; addv[rt<<1|1]+=addv[rt]; maxv[rt<<1]+=addv[rt]; maxv[rt<<1|1]+=addv[rt]; addv[rt]=0; }}void build(int l,int r,int rt){ maxv[rt]=addv[rt]=0; if(l==r) return ; int m=(l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1);}void Update(int L,int R,int l,int r,int rt,int v){ if(l>=L&&r<=R) { addv[rt]+=v; maxv[rt]+=v; return ; } PushDown(rt); int m=(l+r)>>1; if(m>=L) Update(L,R,l,m,rt<<1,v); if(m<R) Update(L,R,m+1,r,rt<<1|1,v); PushUp(rt);}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,n,m,p,q; scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&n,&m,&p,&q); memset(shot,0,sizeof(shot)); for(int i=0;i<=n;++i) shot[i].clear(); int k,L,R,last; scanf("%d",&k); while(k--) { scanf("%d%d",&L,&R); shot[L].push_back(make_pair(R,min(R+q-1,m))); } for(int i=1;i<=n;++i) sort(shot[i].begin(),shot[i].end()); build(1,m,1); double ans=0,r=1.0/(n-p+1); for(int i=1;i<=n;++i) { if(i<=n) { last=0; for(int j=0;j<(int)shot[i].size();++j) { L=shot[i][j].first; R=shot[i][j].second; if(R<=last) continue; L=max(L,last+1); Update(L,R,1,m,1,1); last=R; } } if(i>=p) { k=i-p; if(k) { last=0; for(int j=0;j<(int)shot[k].size();++j) { L=shot[k][j].first; R=shot[k][j].second; if(R<=last) continue; L=max(L,last+1); Update(L,R,1,m,1,-1); last=R; } } ans+=r*maxv[1]; } } printf("%.2lf\n",ans); } return 0;}
0 0
- zoj 3597 Hit the Target! (线段树)
- zoj zju 3597 Hit the Target! 线段树 扫描线
- Hit the Target!
- 求大神路过指导ZOJ3597 Hit the Target!
- ZOJ 1610Count the Colors//线段树
- zoj 1610 Count the Colors【线段树】
- zoj 1610 Count the Colors[线段树]
- 【线段树】Count the Colors (zoj 1610)
- ZOJ 3772 Calculate the Function( 线段树 )
- 【ZOJ】3299 Fall the Brick 线段树
- zoj 1610 Count the Colors(线段树)
- zoj 1610 Count the Colors 线段树
- ZOJ 3299 Fall the Brick (线段树)
- ZOJ - 1610 Count the Colors(线段树)
- ZOJ 1610 Count the Colors【线段树】
- zoj 1601 Count the Colorst(线段树)
- ZOJ----1610-Count the Colors(线段树)
- ZOJ 3772Calculate the Function(线段树)
- linux服务配置之Iptables
- XTUOJ 1142 Collatz Conjecture(数论)
- popToViewController用法
- scala
- levelDB源码笔记(4)- SkipList
- zoj 3597 Hit the Target! (线段树)
- 杂记
- 题集1
- 【足迹】学习C++ primer
- 通信协议中三次握手的故事<转http://blog.sina.com.cn/heinhe >
- 正则表达式
- -------------别人解决的, rtmp中音频和视频数据不对称导致的卡顿的情况-----------------
- 二维坐标中一个移动矩形块中的最大和值
- 全面分析 Spring 的编程式事务管理及声明式事务管理