题目描述

给出一个长度为 n 宽度为 1 ,高度无限的水箱,有 n−1  个挡板将其分为 n 个 1 - 1 的小格,然后向每个小格中注水,水如果超过挡板就会溢出到挡板的另一边,这里的水是满足物理定律的(在无挡板阻拦的情况下会向低处流),现在有 m  个条件 (i,y,k) ,表示从左到右数的第 i 个格子中,在高度为 y+0.5  的地方是否有水,k=1 表示有水,k=0 表示没有水,请求出这 m 个条件最多能同时满足多少个条件。本题有多组数据。

输入格式

第一行一个正整数 T ,为数据组数。
第二行两个正整数 n 、m ,中间用空格隔开。
接下来一行 n−1 个整数,表示从左到右每一块隔板的高度。
接下来 m 行,每行三个整数 i 、y 、k ,表示一个条件。

输出格式

共 T 行,每行对应一组数据的答案。

样例

样例输入

2
3 4
3 4
1 3 1
2 1 0
2 2 0
3 3 1
2 2
2
1 2 0
1 2 1

样例输出

3
1

数据范围与提示

对于 20% 的数据,n,m≤16;
对于另外 10% 的数据,只存在指明某处有水的条件;
对于另外 30% 的数据,n,m≤1000;
对于 100% 的数据,n,m≤1e5,T≤5;

看到这道题,首先应该想到最高的隔板把整个区间分割成两个独立的部分,所以对于整段的答案,可以是左右两个部分的独立的答案(即水没有淹没最高的那个隔板),或者先把两个部分淹没,让水没过最高的隔板,然后在两侧最近的更高的隔板(箱壁可视为无限高的隔板)的高度以下讨论答案。

我用的是线段树维护区间最高挡板位置,用可并堆维护区间所有要求。

初始时,对于每一个单位水槽,把它上方所有要求按高度维护小根堆,合并时就先直接合并它左右两个部分,再将堆中左右小于两侧隔板高度的要求按照顺序提出来,枚举淹没高度,用前缀有水条件个数加后缀无水条件个数更新答案,设这个答案最大值为sum。

对于区间[L,R],若L=R,ans(L,R)=sum。

否则,[L,R]一定能从最高的隔板处分为[L,k],[k+1,R],两个部分,

可以用ans(L,k)+ans(k+1,R)+高于第k和第k+1之间的隔板低于L外侧隔板且低于R外侧隔板间所有无水条件的个数更新答案,

也可以用所有[L,R]之间低于第k和第k+1之间的隔板的有水条件个数+sum更新答案。

是的有点像分治...

复杂度分析的话,每个隔板可以和左侧比它高的第一个隔板和右侧比它高的第一个隔板分别形成两个区间,所以大概有2n个区间吧...然后每个要求在可并堆中共计被访问一次,删除一次,所以再加一个mlogm,肯定是能过的。

AC代码如下:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 200020
#define mid (l+r>>1)
using namespace std;
int read(){
int nm=0,fh=1;char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
struct req{int pos,hs,tpe;}p[M];
bool cmp(req i,req j){
if(i.pos==j.pos) return i.hs<j.hs;
return i.pos<j.pos;
}
int n,m,T,tmp,L[M],R[M],c[M<<2],t[M],ans,rt[M<<2],f[M<<2];
int tot[M<<2],dst[M<<2],son[M][2],fs[M],gt[M],pre[M],suf[M],tk;
void build(int x,int l,int r){
if(l==r){c[x]=l;return;}
build(x<<1,l,mid),build(x<<1|1,mid+1,r);
if(t[c[x<<1]]>t[c[x<<1|1]]) c[x]=c[x<<1];
else c[x]=c[x<<1|1];
}
int top(int x,int l,int r,int lt,int rt){
if(rt<l||r<lt) return lt;
if(lt<=l&&r<=rt) return c[x];
int t1=top(x<<1,l,mid,lt,rt),t2=top(x<<1|1,mid+1,r,lt,rt);
return t[t1]>t[t2]?t1:t2;
}
int merge(int x,int y){
if(x*y==0) return x+y;
if(p[x].hs>p[y].hs) return merge(y,x);
int t1=son[x][0],t2=son[x][1],k=merge(t2,y);
son[x][1]=k;
if(dst[k]>dst[t1]) swap(k,t1);
dst[x]=dst[k]+1,son[x][0]=t1,son[x][1]=k;
return x;
}
int del(int x){
int t1=son[x][0],t2=son[x][1];
son[x][0]=son[x][1]=dst[x]=0;
return merge(t1,t2);
}
void dp(int &x,int l,int r){
x=++tmp,f[x]=tot[x]=0;
int cnt=0,rf=min(t[l-1],t[r]),sum=0;
if(l==r) rt[x]=fs[l];
else{
int tp=top(1,1,n-1,l,r-1);
dp(L[x],l,tp),dp(R[x],tp+1,r);
rt[x]=merge(rt[L[x]],rt[R[x]]);
tot[x]=tot[L[x]]+tot[R[x]];
}
while(rt[x]>0){
if(p[rt[x]].hs>=rf) break;
if(p[rt[x]].tpe==1) tot[x]++;
gt[++cnt]=rt[x],rt[x]=del(rt[x]);
}
suf[cnt+1]=0,pre[0]=0;
for(int i=1;i<=cnt;i++){
pre[i]=pre[i-1],suf[cnt-i+1]=suf[cnt-i+2];
if(p[gt[i]].tpe==1) pre[i]++;
if(p[gt[cnt-i+1]].tpe==0) suf[cnt-i+1]++;
}
for(int i=0;i<=cnt;i++){
if(p[gt[i]].hs==p[gt[i+1]].hs&&i!=0) continue;
sum=max(sum,pre[i]+suf[i+1]);
}
if(l==r){f[x]=sum;return;}
f[x]=max(f[L[x]]+f[R[x]]+suf[1],tot[L[x]]+tot[R[x]]+sum);
}
int main(){
T=read();
while(T--){
n=read(),m=read(),tmp=ans=tk=0,t[0]=t[n]=2147483646;
memset(fs,0,sizeof(fs));
for(int i=1;i<n;i++) t[i]=read();
for(int i=1;i<=m;i++) p[i].pos=read(),p[i].hs=read(),p[i].tpe=read();
build(1,1,n-1),sort(p+1,p+m+1,cmp);
for(int i=1;i<=m;i++){fs[p[i].pos]=merge(i,fs[p[i].pos]);}
dp(tk,1,n),printf("%d\n",f[tk]);
}
return 0;
}

  

雅礼集训 2017 Day2 水箱 可并堆的更多相关文章

  1. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  2. #6034. 「雅礼集训 2017 Day2」线段游戏 李超树

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...

  3. 【loj6034】「雅礼集训 2017 Day2」线段游戏

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:Special Judge 上传者: 匿名 题目描述 ...

  4. loj #6032. 「雅礼集训 2017 Day2」水箱 线段树优化DP转移

    $ \color{#0066ff}{ 题目描述 }$ 给出一个长度为 \(n\) 宽度为 \(1\) ,高度无限的水箱,有 \(n-1\) 个挡板将其分为 \(n\) 个 \(1 - 1\) 的小格, ...

  5. 「雅礼集训 2017 Day2」水箱 (数据结构+dp ,一个log)

    题面 题解 在网上看到有些做法,有什么平衡树.启发式合并等等总之复杂度O(Tnlog^2(n))的不优做法,这里我就用一个O(Tnlogn)的做法好了 其实大体上推导的思路都是一样的. 我们很容易发现 ...

  6. loj#6032. 「雅礼集训 2017 Day2」水箱(并查集 贪心 扫描线)

    题意 链接 Sol 神仙题+神仙做法%%%%%%%% 我再来复述一遍.. 首先按照\(y\)坐标排序,然后维护一个扫描线从低处往高处考虑. 一个连通块的内状态使用两个变量即可维护\(ans\)表示联通 ...

  7. LOJ#6032. 「雅礼集训 2017 Day2」水箱

    传送门 首先可以有一个平方复杂度的 \(DP\) 设 \(f_{i,j}\) 表示前面 \(i\) 个小格,高度为 \(j\) 的最大答案 令 \(h_i\) 表示隔板 \(i\) 的高度 当 \(j ...

  8. 「雅礼集训 2017 Day2」水箱

    题目链接 题意分析 我们用\(f[i][j]\)表示当前到达第\(i\)个位置水位高度为\(j\)的答案 如果那么\(h[i]\)为\(i\)和\(i+1\)之间的支柱高度 那么如果\(j≤h[i]\ ...

  9. loj#6033. 「雅礼集训 2017 Day2」棋盘游戏(二分图博弈)

    题意 链接 Sol 第一次做在二分图上博弈的题..感觉思路真是清奇.. 首先将图黑白染色. 对于某个点,若它一定在最大匹配上,那么Bob必胜.因为Bob可以一直沿着匹配边都,Alice只能走非匹配边. ...

随机推荐

  1. 洛谷P2661 信息传递==coedevs4511 信息传递 NOIP2015 day1 T2

    P2661 信息传递 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知 ...

  2. Just a Hook(线段树)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. 频繁加载、删除swf造成flash崩溃解决办法

    最近在项目中遇到flash崩溃问题,经分析,都是在swfobject.embedSWF这一步卡死,页面及flash均无反应.   造成此问题的场景是,在同一根节点上频繁清空节点.调用swfobject ...

  4. Ogbect对象转换为泛型对象

    相信很多人都自己写个这个转换的方法,再次附上我自己的写转换方法仅供参考. T t = BeanUtil.dbObject2Bean(obj, tClass); public static <T& ...

  5. ubuntu 安装wine

    笔记 1.安装源 sudo add-apt-repository ppa:wine/wine-builds sudo apt-get update 2.安装wine sudo apt-get inst ...

  6. elasticsearch从入门到出门-06-剖析Elasticsearch的基础分布式架构

    这个图来自中华石杉:

  7. Residual (numerical analysis)

    In many cases, the smallness of the residual means that the approximation is close to the solution, ...

  8. "ORA-01012: not logged on"以及"Connected to an idle instance."解决思路

    今天测试用的ORACLE服务器出现卡顿情况,于是准备重启一下,在运行shutdown指令关闭数据库的时候意外断开连接,后面想再次进入ORACLE服务器启动时便遇见如下报错: 使用sqlplus /no ...

  9. Redis的主从同步手动执行故障切换

    1.准备三个redis配置文件,通过端口的区分,启动三个redis数据库实例,然后配置主从复制. # a6371.conf port 6371 daemonize yes pidfile /data/ ...

  10. centos6安装nginx最详细步骤

    第一步:在centos下面下载 nginx          wget http://nginx.org/download/nginx-1.2.9.tar.gz 解压 tar zxf nginx-1. ...