链接:http://icpc.upc.edu.cn/problem.php?cid=1803&pid=13

题意:给出一个n,接下来一行给出n个数。才开始所有数为0,每次操作可以选一个区间[l,r]使得区间内的数全部+1。问最少的操作次数得到这个序列,并且输出每步的区间。

思路:线段树维护区间内的最小数以及下标。枚举左端点,右端点肯定越大越优。每次先找出a[i]剩下多少,再迭代的从[i,n]区间中找可行的最靠右的最小值(假设下标为r),每次更新[i,r]的值,直到a[i]减为0。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+10;
int n,a[N],minval,minpos;
struct Node
{int l,r,val,pos,lazy;//val:[l,r]中最小的值,pos是下标 //lazy:val的该变量
}tree[N<<2];
//答案
struct node
{int l,r,num;node(){}node(int l,int r,int num):l(l),r(r),num(num){}
}ans[N];
void pushup(int cur)
{tree[cur].val=min(tree[cur<<1].val,tree[cur<<1|1].val);if(tree[cur<<1].val<=tree[cur<<1|1].val)tree[cur].pos=tree[cur<<1].pos;elsetree[cur].pos=tree[cur<<1|1].pos;return ;
}
//区间更新值,lazy标记
void pushdown(int cur)
{if(tree[cur].lazy){tree[cur<<1].lazy+=tree[cur].lazy;tree[cur<<1].val+=tree[cur].lazy;tree[cur<<1|1].lazy+=tree[cur].lazy;tree[cur<<1|1].val+=tree[cur].lazy;tree[cur].lazy=0;}return ;
}
void build(int l,int r,int cur)
{tree[cur].l=l;tree[cur].r=r;tree[cur].lazy=0;if(l==r){tree[cur].val=a[l];tree[cur].pos=l;return ;}int m=(l+r)>>1;build(l,m,cur<<1);build(m+1,r,cur<<1|1);pushup(cur);return;
}
void update(int l,int r,int cur,int val)
{if(l<=tree[cur].l&&tree[cur].r<=r){tree[cur].val+=val;tree[cur].lazy+=val;     return ;}pushdown(cur);if(l<=tree[cur<<1].r) update(l,r,cur<<1,val);if(r>=tree[cur<<1|1].l) update(l,r,cur<<1|1,val);pushup(cur);return ;
}
int query(int l,int r,int cur)
{int res=N;if(l<=tree[cur].l&&tree[cur].r<=r){//更新该区间的最小值以及下标 if(tree[cur].val<=minval){minval=tree[cur].val;minpos=tree[cur].pos;   }return tree[cur].val;}pushdown(cur);//先查左子树再查右子树,保证是最右的可行端点。 if(l<=tree[cur<<1].r) res=query(l,r,cur<<1);if(r>=tree[cur<<1|1].l) res=min(res,query(l,r,cur<<1|1));pushup(cur);return res;
}
int main(void)
{int cnt=0,sum=0,val,r;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);build(1,n,1);for(int l=1;l<=n;l++){minval=N;val=query(l,l,1);    if(!val) continue;r=n;//尽可能往右,这样次数才更少,答案更优。 //迭代改变a[l]的值 while(val){minval=N;query(l,r,1);val-=minval;if(minval)//minval如果为0,该答案不用记 {sum+=minval,ans[cnt++]=node(l,r,minval);update(l,r,1,-minval); }      //minpos的数已变为0,再从[l,minspos-1]找最小值。 r=minpos-1;}}       printf("%d\n",sum);for(int i=0;i<cnt;i++){for(int j=0;j<ans[i].num;j++)printf("%d %d\n",ans[i].l,ans[i].r);}return 0;
}

石油大 2019年第二阶段我要变强个人训练赛第十八场 Problem N 扶桑号战列舰(线段树+区间更新+区间查询)相关推荐

  1. Contest1802 - 2019年第二阶段我要变强个人训练赛第十八场 问题 N: 扶桑号战列舰 线段树+贪心

    题目链接:http://icpc.upc.edu.cn/problem.php?cid=1802&pid=13 问题 N: 扶桑号战列舰 时间限制: 1 Sec  内存限制: 128 MB   ...

  2. 2019年第二阶段我要变强个人训练赛第十八场 扶桑号战列舰(线段树+递归)

    问题 N: 扶桑号战列舰 时间限制: 1 Sec  内存限制: 128 MB  Special Judge 题目描述 众所周知,一战过后,在世界列强建造超无畏级战列舰的竞争之中,旧日本海军根据&quo ...

  3. 石油大 Contest1777 - 2019年第二阶段我要变强个人训练赛第九场 I 热狗树(树形dp)

    题目描述 "我是番茄酱!" "我是黄芥末酱!" "合在一起就是--美式热狗上加的,那个!" 热狗树上的每个节点都涂有番茄酱或者黄芥末酱中的一 ...

  4. 石油大--2020年秋季组队训练赛第十二场----J、Greedy Termite(线段树)

    题面: 题意: 给定正整数 nnn 和起始位置 sss. nnn 表示有 nnn 个杆子,每个杆子由属性 (xi,hi)(x_i,h_i)(xi​,hi​) 构成,表示在 xix_ixi​ 处有一根高 ...

  5. 石油大--2020年秋季组队训练赛第十二场---- L、The Assembly Code(模拟)

    题面: 题意: 就是题目有点长,写起来直接写就好啦. 有一个长度为 232,0≤i<2322^{32},0\le i <2^{32}232,0≤i<232 数组 MMM , MiM_ ...

  6. Contest1819 - 2019年我能变强组队训练赛第十一场(补题场)

    赛后总结 菜 问题 E: Faulhaber's Triangle 问题 E: Faulhaber's Triangle 单纯模拟题,模拟分数加法 代码 #include <bits/stdc+ ...

  7. Contest1819 - 2019年我能变强组队训练赛第十一场

    题目: The King's Ups and Downs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  8. HDU2665(函数式线段树-区间第K大)

    题目:K-th Number 如果求区间第K小,就转换一下就行了,假设你要求区间[u,v]的第k小,那就是第v-u+1-k大 #include<stdio.h> #include<a ...

  9. BZOJ4034 树上操作(树剖 线段树大模板)

    BZOJ4034 long long 是大坑点 貌似long long 跟int 乘起来会搞事情?... A了这题线段树和树剖的基础OK 嘛 重点过掉的还是线段树区间更新的lazy tag吧 #inc ...

最新文章

  1. C++ stringstream 简化数据类型转换
  2. java getresourceasstream null_java踩坑记-getResourceAsStream
  3. windows中遍历指定文件夹下的所有子文件夹
  4. 二零一三年计算机视觉代码合集
  5. redis-4.0.10集群安装(3台机器,6个node),以及在Spring项目中的集成,redis操作工具类
  6. 如何使用oprofile对软件做profiling
  7. Could not load the Tomcat server configuration at \Servers\Tomcat v7.0 Server at localhost-config
  8. 云+X案例展 | 民生类: “中企通信 × TutorABC”共创全球数字教育科技新里程
  9. android opencv 银行卡识别,NDK 开发之使用 OpenCV 实现银行卡号识别
  10. (26)计数器verilog与VHDL编码(学无止境)
  11. python 判断线程状态_Python 线程和进程
  12. java application_applet_Java程序可以分为JavaApplication和JavaApplet两类。()
  13. 三线压力传感器原理_电喷摩托车进气压力传感器原理与检测
  14. (转)利用个人电脑搭建网站WEB服务器域名访问
  15. 【进销存管理系统——开题报告 分享(仅供参考呀)】
  16. 计算机硬盘图标怎么更改,硬盘图标怎么改 更改本地磁盘图标方法
  17. Bluefish 1.1.3
  18. 《少有人走过的路–心智成熟的旅程》读书笔记
  19. 光纤接入实现模式 P2P和PON。PON原理介绍。
  20. 有限责任公司破产清算程序有哪些

热门文章

  1. NOIP学习之综合应用:177.八进制到十进制
  2. CMMI的五个等级是什么?
  3. js根据经纬度计算两点距离
  4. 电视台以IPTV系统为载体扩展融媒体解决方案
  5. (JAVA)国际跳棋--棋里乾坤
  6. 联想微型计算机620S,小巧机身强劲性能 试用联想ideacentre 620s
  7. android上传图片到PHP后台全过程
  8. X79G Xeon 2630v2 电脑 Hackintosh 黑苹果efi引导文件
  9. PTcms精美小说阅读网站源码/带采集规则
  10. 建立第一个Power Apps程序(新手版)