bzoj-2527 Meteors
来源:互联网 发布:js获取div的id值 编辑:程序博客网 时间:2024/05/18 03:50
题意:
有一个星球,它的轨道被划分成m份,由n个国家占领;
一个国家可能占领多个轨道段;
现有q次事件,每次在一个轨道区间上每段落下Ai量的流星雨;
每个国家需要一定量的流星雨,当然它所得的为它占领的轨道段所得之和;
求每个国家所需的东西什么时候可以满足,如果始终不能满足输出NIE;
题解:
这题我第一眼看成了输出TAK或NIE;
结果仔细看看我选择死亡;
边处理事件边判断是否满足答案这个复杂度无论如何都无法接受;
所以要将事件离线下来处理;
另一个思路就是可持久化线段树;
建树的时候只会更改logm个结点,复杂度O(qlogm);
查询二分答案,复杂度O(n*logq*logm);
这样的时间复杂度是可以的啦,然而我们来算算空间;
线段树里要开qlogm个结点,两个long long占16字节;
算一下是80多兆了,似乎实现上就爆掉了?所以这个思路不可行;
我们并不能对时间预处理然后二分,那在二分的过程中处理事件;
只维护一个普通的线段树,那么执行一次二分是O(qlogqlogm)的;
然后复杂度O(nq*logqlogm)这比暴力还挫的复杂度。。
当然不是这样!我们把所有的n一起二分!
每次二分事件区间[l,r],将线段树调整至mid处;
然后统计所有的国家是否满足它的要求;
如果满足,则将其扔到[l,mid]再二分,满足则扔到[mid+1,r];
l==r记录一下答案就好啦!
复杂度O((q+n)logqlogm)?大概就是这么个东西;
好久不写数据结构写写还有点小激动呢2333;
代码:
#include<stdio.h>#include<string.h>#include<algorithm>#define N 310000#define lson l,mid,no<<1#define rson mid+1,r,no<<1|1using namespace std;typedef long long ll;struct node{int no,need,head;}c[N];int next[N],to[N],ce;int L[N],R[N],a[N];int n,m,T;ll sum[N<<2],cov[N<<2];int ans[N];bool vis[N];void Pushup(int no){sum[no]=sum[no<<1]+sum[no<<1|1];}void Pushdown(int no,int len){if(cov[no]){cov[no<<1]+=cov[no];cov[no<<1|1]+=cov[no];sum[no<<1]+=cov[no]*(len-(len>>1));sum[no<<1|1]+=cov[no]*(len>>1);cov[no]=0;}}void update(int l,int r,int no,int st,int en,int val){if(st<=l&&r<=en){cov[no]+=val;sum[no]+=(ll)val*(r-l+1);}else{Pushdown(no,r-l+1);int mid=l+r>>1;if(en<=mid)update(lson,st,en,val);else if(st>mid)update(rson,st,en,val);elseupdate(lson,st,en,val),update(rson,st,en,val);Pushup(no);}}ll query(int l,int r,int no,int x){if(l==r)return sum[no];else{Pushdown(no,r-l+1);int mid=l+r>>1;if(x<=mid)return query(lson,x);elsereturn query(rson,x);}}void add(int x,int y){to[++ce]=y;next[ce]=c[x].head;c[x].head=ce;}void slove(int l,int r,int st,int en){if(st>en)return ;if(l==r){for(int i=st;i<=en;i++)ans[c[i].no]=l;return ;}int mid=l+r>>1;while(mid>T){if(L[T+1]<=R[T+1])update(1,m,1,L[T+1],R[T+1],a[T+1]);elseupdate(1,m,1,L[T+1],m,a[T+1]),update(1,m,1,1,R[T+1],a[T+1]);T++;}while(mid<T){if(L[T]<=R[T])update(1,m,1,L[T],R[T],-a[T]);elseupdate(1,m,1,L[T],m,-a[T]),update(1,m,1,1,R[T],-a[T]);T--;}int i,j,cnt;ll temp;for(i=st,cnt=0;i<=en;i++){for(j=c[i].head,temp=0;j;j=next[j]){temp+=query(1,m,1,to[j]);if(temp>=c[i].need)break;}if(temp>=c[i].need)vis[i]=1,cnt++;elsevis[i]=0;}for(i=st,j=st;i<=en;i++){if(vis[i])swap(c[i],c[j++]);}slove(l,mid,st,st+cnt-1);slove(mid+1,r,st+cnt,en);}int main(){int q,i,j,k,x,y;scanf("%d%d",&n,&m);for(i=1;i<=m;i++)scanf("%d",&x),add(x,i);for(i=1;i<=n;i++)scanf("%d",&c[i].need),c[i].no=i;scanf("%d",&q);for(i=1;i<=q;i++)scanf("%d%d%d",L+i,R+i,a+i);q++;L[q]=1,R[q]=m,a[q]=1e9;slove(1,q,1,n);for(i=1;i<=n;i++)if(ans[i]!=q)printf("%d\n",ans[i]);elseputs("NIE");return 0;}
0 0
- 【BZOJ 2527】 [Poi2011]Meteors
- bzoj-2527 Meteors
- BZOJ 2527: [Poi2011]Meteors
- bzoj 2527 [Poi2011]Meteors
- BZOJ 2527 [Poi2011] Meteors
- BZOJ 2527 Meteors(整体二分)
- BZOJ 2527: [Poi2011]Meteors 整体二分
- BZOJ 2527 Meteors (整体二分)
- BZOJ 2527: [Poi2011]Meteors【整体二分】
- 【bzoj 2527】Meteors(整体二分)
- bzoj 2527: [Poi2011]Meteors 整体二分
- bzoj 2527: [Poi2011]Meteors (树状数组+整体二分)
- bzoj 2527: [Poi2011]Meteors cdq分治+树状数组
- 【BZOJ】2527 [Poi2011]Meteors 整体二分+树状数组
- BZOJ 2527 [Poi2011]Meteors [整体二分+线段树]
- BZOJ 2527: [Poi2011]Meteors 整体二分 树状数组
- [整体二分+树状数组]BZOJ 2527——[Poi2011]Meteors
- bzoj 2527 [Poi2011]Meteors 整体二分+树状数组
- 网络编程1--UDP
- ZOJ.1730 Crazy Tea Party 2015/09/22
- [KMP][HDU3336][Count the string]
- 移动IM开发学习<3>
- iOS蓝牙相关文章
- bzoj-2527 Meteors
- spring mvc 事务不生效 不回滚
- hdu 5434 Peace small elephant
- Peeking Iterator
- 表头浮动特效资源放送
- 关于php的思考
- Oracle中如何插入特殊字符: & 和 ' (多种解决方案)
- MyBatis中对List<Object> 对象List的批处理插入操作
- Mysql 常用查询函数