整体二分的题

以前没有写过整体二分的题,感受了一下

大概是把答案和所有的询问一同二分,就是把满足当前二分区间的询问和不满足的分开后递归下去

复杂度由主定理保证,里面的复杂度必须是之和二分后的区间线性相关,而不是与整个区间相关,复杂度才有保证

有点cdq的感觉

代码 :

#include<bits/stdc++.h>
#define LL long long
using namespace std;#define INF 1000000000
#define MAXN 300005int n,m,t,id[MAXN],Ml[MAXN],Mr[MAXN],A[MAXN],mis[MAXN];
int head[MAXN],to[MAXN*2];
int ans[MAXN];namespace SegmentTree{const int L=0,R=1;struct node{int son[2];LL add;}x[MAXN*2];int sz=1;void _init(int l,int r,int num) {if(l==r) return;int mid=l+r>>1;x[num].son[L]=++sz;x[num].son[R]=++sz;_init(l,mid,x[num].son[L]);_init(mid+1,r,x[num].son[R]);}void Add(int l,int r,int nl,int nr,int num,int v) {if(l==nl&&r==nr) {x[num].add+=v;return;}int mid=nl+nr>>1;if(l>mid) Add(l,r,mid+1,nr,x[num].son[R],v);else if(r<=mid) Add(l,r,nl,mid,x[num].son[L],v);else {Add(l,mid,nl,mid,x[num].son[L],v);Add(mid+1,r,mid+1,nr,x[num].son[R],v);}}LL Qurey(int pos,int l,int r,int num) {if(l==r) return x[num].add;int mid=l+r>>1;if(pos<=mid) return Qurey(pos,l,mid,x[num].son[L])+x[num].add;else return Qurey(pos,mid+1,r,x[num].son[R])+x[num].add;}
}
#define ST SegmentTreebool f[MAXN];
void solve(int l,int r,int L,int R) {if(l>r) return;if(L==R) {for(int i=l;i<=r;i++) ans[id[i]]=L;return;}int mid=L+R>>1;for(int i=L;i<=mid;i++) {if(Ml[i]<=Mr[i]) ST::Add(Ml[i],Mr[i],1,m,1,A[i]);else {ST::Add(Ml[i],m,1,m,1,A[i]);ST::Add(1,Mr[i],1,m,1,A[i]);}}for(int i=l;i<=r;i++) {LL get=0;for(int j=head[id[i]];j;j=to[j]) {get+=ST::Qurey(j,1,m,1);if(get>=mis[id[i]]) break;}if(get<mis[id[i]]) f[id[i]]=1,mis[id[i]]-=get;}int p1=l,p2=r;while(p2>p1) {while(p2>p1&&!f[id[p1]]) p1++;while(p2>p1&&f[id[p2]]) p2--;if(p2>p1) swap(id[p1],id[p2]);}p1=l-1;for(int i=l;i<=r;i++) {if(!f[id[i]]) p1=i;f[id[i]]=0;}for(int i=L;i<=mid;i++) {if(Ml[i]<=Mr[i])    ST::Add(Ml[i],Mr[i],1,m,1,-A[i]);else {ST::Add(Ml[i],m,1,m,1,-A[i]);ST::Add(1,Mr[i],1,m,1,-A[i]);}}solve(l,p1,L,mid);solve(p1+1,r,mid+1,R);
}int main() {scanf("%d%d",&n,&m);for(int a,i=1;i<=m;i++) {scanf("%d",&a);to[i]=head[a];head[a]=i;}for(int i=1;i<=n;i++) {scanf("%d",&mis[i]);id[i]=i;}scanf("%d",&t);for(int i=1;i<=t;i++) {scanf("%d%d%d",&Ml[i],&Mr[i],&A[i]);}A[++t]=INF;Ml[t]=1;Mr[t]=m;ST::_init(1,m,1);solve(1,n,1,t);for(int i=1;i<=n;i++) {if(ans[i]==t) puts("NIE");else printf("%d\n",ans[i]);}return 0;
}
#undef ST

转载于:https://www.cnblogs.com/ihopenot/p/6164321.html

Bzoj2527--Poi2011Meteor相关推荐

  1. [bzoj2527][Poi2011]Meteors_整体二分_树状数组

    Meteors bzoj-2527 Poi-2011 题目大意:题目链接. 注释:略. 想法: 首先答案可以离线,且具有单调性. 这里的单调性就是随着时间的推移,每个国家收集的陨石数增加. 不难想到整 ...

  2. [BZOJ2527]Meteors

    整体二分挺好玩的...学一发 这个询问显然是可以二分的,但每次都二分就会T爆,所以我们有了"整体"二分 每次处理一些询问,要求这些询问的答案一定在$[l,r]$中 先把$l$到$m ...

  3. bzoj2527: [Poi2011]Meteors

    整体二分天数,然后用树状数组记录每个点采集点收集的陨石个数,暴力计算对于某个国家,是否达到要求,因为在计算过程中可能爆LL,所以边加边判. 我怎么老是把m打成n啊 #include<cstdio ...

  4. BZOJ 2527 Meteors | 整体二分

    BZOJ 2527 Meteors 题意 一个圆环上有m个位置,编号为1~m,分别属于n个国家. 有k个时刻,每个时刻都会给圆环上的一个区间中每个位置的值加上一个数. 每个国家有一个目标,问对于每个国 ...

最新文章

  1. 常见Jvm面试题总结及答案整理 120道(持续更新)
  2. axios与ajax区别
  3. ept技术_EPT技术在压载水处理中的运用
  4. 前端组件化-抽象公共组件类
  5. android tcp判断服务器是否断开,Android tcp客户端连接,然后从java服务器断开连接...
  6. HBuilder的快捷操作
  7. 【算法分析与设计】最大连续子序列和问题
  8. html水调歌头实验总结,水调歌头明月几时有反思小结
  9. 服务器系统咋关机呀,各种服务器系统的关机
  10. 将计算机网口虚拟串口软件,虚拟串口及其在串口转以太网中的应用
  11. oppo手机热点Android,OPPO手机怎么开启热点?OPPO手机共享网络的三种方法
  12. HDU 6070 Dirt Ratio
  13. php guzzlehttp,PHP 使用 Guzzle 发送 HTTP 请求
  14. uni-app 微信小程序启用组件按需注入
  15. AI配对真能解决“单身公害”?
  16. 深度学习算法中卷积神经网络的应用
  17. android 怎样删除sim卡中的联系人
  18. 麦克风阵列研究3 定向录音
  19. php中使用soap的建立共享接口
  20. 超强反爬虫方案!Requests 什么的通通爬不了

热门文章

  1. 符号_液压图形符号识别之流量控制阀符号原理
  2. php生成静态页面的方法,php生成静态页面的办法
  3. 修改mysql连接回收时间_Druid无效链接回收策略(源码分析)(mysql 8小时连接失效问题)...
  4. Jackson解析XML
  5. 6.5. Properties
  6. c# 添加外部程序集相对引用问题
  7. ORA-03113: 通信通道的文件结尾 进程 ID: 764 会话 ID: 125 序列号: 5
  8. 图论+dp poj 1112 Team Them Up!
  9. PHP面向对象之继承和多态
  10. 新手上路学习配置C,C++,GTK等开发环境