[jzoj5073 GDOI2017第二轮模拟] 影魔
Description
每一个灵魂,都有着自己的战斗力,而影魔,靠这些战斗力提升自己的攻击。
奈文摩尔有n个灵魂,他们在影魔宽广的体内可以排成一排,从左至右标号1到n。第i个灵魂的战斗力为k[i],灵魂们以点对的形式为影魔提供攻击力,对于灵魂对i,j(i<j)来说,若不存在k[s](i<s<j)大于k[i]或者k[j],则会为影魔提供p1的攻击力(可理解为:当j=i+1时,因为不存在满足i<s<j的s,从而k[s]不存在,这时提供p1的攻击力;当j>i+1时,若max{k[s]|i<s<j}<=min{k[i],k[j]},则提供p1的攻击力);另一种情况,令c为k[i+1],k[i+2],k[i+3]……k[j-1]的最大值,若c满足:k[i]<c<k[j],或者k[j]<c<k[i],则会为影魔提供p2的攻击力,当这样的c不存在时,自然不会提供这p2的攻击力;其他情况的点对,均不会为影魔提供攻击力。
影魔的挚友噬魂鬼在一天造访影魔体内时被这些灵魂吸引住了,他想知道,对于任意一段区间[a,b],1<=a<b<=n,位于这些区间中的灵魂对会为影魔提供多少攻击力,即考虑所有满足a<=i<j<=b的灵魂对i,j提供的攻击力之和。
顺带一提,灵魂的战斗力组成一个1到n的排列:k[1],k[2],…,k[n]。
Input
第一行n,m,p1,p2
第二行n个数:k[1],k[2],…,k[n]
接下来m行,每行两个数a,b,表示询问区间[a,b]中的灵魂对会为影魔提供多少攻击力。
Output
共输出m行,每行一个答案,依次对应m个询问。
Sample Input
Sample Output
Data Constraint
另30%: p1=2*p2。
100%:1 <= n,m <= 200000;1 <= p1,p2 <= 1000。
Solution
把所有询问离线
用单调栈分别做两次,求出对于排列数组的单个元素从自己开始到左边和到右边的最远的端点
为了处理贡献对应询问的区间建出一颗线段树
按左端点排序询问,枚举区间内的元素,设当前元素为最大值,那么,从它到区间端点(端点作为最大值)的这个区间的都可以打上p2贡献的标记
设当前元素为次小值,那么,对区间端点打上p1-p2-p2的标记(作为次小有两次重复)
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define _L long long
#define _RG register int
#define lson s, mid, k << 1
#define rson mid + 1, t, k << 1 | 1
const int N = 200010;
int n, m, p1, p2, a[N], l[N], r[N], steck[N], sec, nex[N], tim;
_L tag[N << 2], sum[N << 2], ans[N];
struct Q
{
int l, r, id;
}que[N];
inline void downt(_RG s, _RG t, _RG k)
{
sum[k] += tag[k] * (_L)(t - s + 1);
if(s ^ t) tag[k << 1] += tag[k], tag[k << 1 | 1] += tag[k];
tag[k] = 0;
}
void updat(_RG s, _RG t, _RG k, _RG x, _RG y, _RG z)
{
_RG mid = s + t >> 1;
downt(s, t, k);
if(s ^ t) downt(s, mid, k << 1), downt(mid + 1, t, k << 1 | 1);
if(s == x && t == y)
{
tag[k] += z;
downt(s, t, k);
return;
}
if(y <= mid) updat(lson, x, y, z);
else if(x > mid) updat(rson, x, y, z);
else updat(lson, x, mid, z), updat(rson, mid + 1, y, z);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
_L query(_RG s, _RG t, _RG k, _RG x, _RG y)
{
_RG mid = s + t >> 1;
downt(s, t, k);
if(s ^ t) downt(s, mid, k << 1), downt(mid + 1, t, k << 1 | 1);
if(s == x && t == y) return sum[k];
if(y <= mid) return query(lson, x, y);
if(x > mid) return query(rson, x, y);
return query(lson, x, mid) + query(rson, mid + 1, y);
}
void solve()
{
for(_RG i = 1; i <= m; ++i) que[i] = (Q) {l[i], r[i], i};
std::sort(que + 1, que + 1 + m, [](const Q &u, const Q &v) {return u.l > v.l;});
steck[sec = 1] = n + 1;
a[n + 1] = 1e9;
for(_RG i = n; i; --i)
{
while(sec && a[steck[sec]] < a[i]) --sec;
nex[i] = steck[sec];
steck[++sec] = i;
}
tim = 1;
for(_RG i = n; i; --i)
{
updat(1, n + 1, 1, i + 1, nex[i], p2);
updat(1, n + 1, 1, nex[i], nex[i], p1 - p2 - p2);
while(tim <= m && que[tim].l == i)
{
ans[que[tim].id] += query(1, n + 1, 1, i, que[tim].r);
++tim;
}
if(tim > m) break;
}
}
int main()
{
scanf("%d%d%d%d", &n, &m, &p1, &p2);
for(_RG i = 1; i <= n; ++i) scanf("%d", a + i);
for(_RG i = 1; i <= m; ++i) scanf("%d%d", l + i, r + i);
solve();
memset(sum, 0LL, sizeof sum), memset(tag, 0LL, sizeof tag);
for(_RG i = 1; i <= n / 2; ++i) std::swap(a[i], a[n - i + 1]);
for(_RG i = 1; i <= m; ++i) l[i] = n - l[i] + 1, r[i] = n - r[i] + 1, std::swap(l[i], r[i]);
solve();
for(_RG i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
return 0;
}
枚举当前数为次小值,则可以直接为区间加上贡献,用线段树覆盖,
[jzoj5073 GDOI2017第二轮模拟] 影魔的更多相关文章
- GDOI2017第二轮模拟day1 总结
平民比赛 这场比赛的暴力分非常友好. 但是我并没有拿到全部的暴力分. 1(暴力分\(60/100\)) 暂时我可以拿的暴力分为\(30/100\),直接mst模拟即可. 然而当时打了个辣鸡莫队,结果爆 ...
- 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块
题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...
- 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树
题面 在Byteland一共有n 个城市,编号依次为1 到n,它们之间计划修建m条双向道路,其中修建第i 条道路的费用为ci. Byteasar作为Byteland 公路建设项目的总工程师,他决定选定 ...
- 【JZOJ5071】【GDSOI2017第二轮模拟】奶酪 树形dp
题面 CJY很喜欢吃奶酪,于是YJC弄到了一些奶酪,现在YJC决定和CJY分享奶酪. YJC弄到了n-1块奶酪,于是他把奶酪挂在了一棵n个结点的树上,每根树枝上挂一块奶酪,每块奶酪都有重量. YJC和 ...
- 【JZOJ5068】【GDSOI2017第二轮模拟】树 动态规划+prufer序列
题面 有n个点,它们从1到n进行标号,第i个点的限制为度数不能超过A[i]. 现在对于每个s (1 <= s <= n),问从这n个点中选出一些点组成大小为s的有标号无根树的方案数. 10 ...
- DFRobot万物互联大赛第二轮
前言 最近放在阳台的花草被啥东西给吃了,然后厨房挂在墙上的小虾米也不知道咋的被抓破吃光了(我怀疑是隔隔壁两条泰迪),所以打算做个简单的项目,教训一下偷吃贼.时间比较仓促,内容比较多,能力有比较有限,好 ...
- 【百度之星2014~初赛(第二轮)解题报告】Chess
声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载.可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站 ...
- 腾讯Java程序员第二轮面试11个问题,你会几个?
此前,分享了阿里巴巴.网易.百度等多家名企的JAVA面试题. 这也引来了不少程序员网友们的围观. 其中,也有相当一部分网友是已经从事Java开发好多年的程序员,当他们阅读完JAVA面试题的反应是:一个 ...
- 小米Java程序员第二轮面试10个问题,你是否会被刷掉?
近日,开发者头条上分享了一篇"小米java第二轮面经",有很多的java程序员表示非常有兴趣. 下面l就和各位分享小米java第二轮面经(华为java工程师笔试面试题可以看文章某尾 ...
随机推荐
- the little schemer 笔记(8)
第八章 lambda the ultimate 还记得我们第五章末的rember和insertL吗 我们用equal?替换了eq? 你能用你eq?或者equal?写一个函数rember-f吗 还不能, ...
- 跟我一起玩Win32开发(19):浏览和打开文件
在应用程序中,我们很经常要实现的功能,是Open文件或保存文件对话框,让用户来选择一个或N个文件.本文我将介绍两种思路,第一种方法较为复杂,第二种方法较为简单. 方法一:老规矩 这是一种传统方法,使用 ...
- C++中的定位放置new(placement new)
一般来说,使用new申请空间时,是从系统的“堆”(heap)中分配空间.申请所得的空间的位置时根据当时的内存的实际使用情况决定的.但是,在某些特殊情况下,可能需要在程序员指定的特定内存创建对象,这就是 ...
- 数据库sql 使用 lag 和OVER 函数和 like 使用 小技巧
1. sample 1: Lag()就是取当前顺序的上一行记录.结合over就是分组统计数据的.Lag()函数,就是去上N行的字段的数据. SQL> select * from x; A---- ...
- imagettftext
ImageTTFText 写 TTF 文字到图中. 语法: array ImageTTFText(int im, int size, int angle, int x, int y, int col, ...
- 生产环境中nginx既做web服务又做反向代理
一.写对于初入博客园的感想 众所周知,nginx是一个高性能的HTTP和反向代理服务器,在以前工作中要么实现http要么做反向代理或者负载均衡.尚未在同一台nginx或者集群上同时既实现HTTP又实现 ...
- XSS漏洞解析(三)
系统存在xss漏洞就容易引发CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为: ...
- Log4net系列二:Log4net邮件日志以及授权码
Log4net邮件发送 上篇文章我们主要介绍Log4net生成文本格式,本篇文章主要配置邮箱发送.关于项目的引用,搭建我们就不在描述,如果不太清楚,请看上篇文章, 老规矩,我们现在配置文件中添加一个a ...
- websocket 加layim实现在线聊天系统
实现流程: 1.浏览器连接服务器时保存所有用户id以及对应的唯一session(session用户用户消息推送). 1.1:判断登录用户是否有离线消息(个人消息以及群消息),有则将离线消息进行推送给登 ...
- CF989C A Mist of Florescence
思路: 有趣的构造题. 实现: #include <bits/stdc++.h> using namespace std; ][]; void fillin(int x, int y, c ...