http://www.lydsy.com/JudgeOnline/problem.php?id=4826

吐槽一下bzoj这道题的排版是真丑。。。

我还是粘洛谷的题面吧。。。

提供p1的攻击力:i,j 位置的数是区间[i,j]的最大值和次大值

提供p2的攻击力:i,j位置的数有一个是区间[i,j]的最大值,另一个不是次大值

记录L[i]、R[i] 分别表示i左右第一个大于k[i]的位置

p1的贡献:

1、点对(L[i],R[i])    2、点对(i,i+1)

p2的贡献:

1、点对(L[i],i+1),(L[i],i+2),……,(L[i],R[i]-1) 这些区间的最大值在L[i],次大值在i

2、点对(i-1,R[i]),(i-2,R[i]),……,(L[i+1],R[i]) 这些区间的最大值在R[i],次大值在i

然后问题就变成了

二维平面上单点修改,区间修改,矩阵查询

主席树(或许它叫可持久化线段树)可搞

第i颗线段树维护前i行的信息

主席树实现区间修改时出现了个bug,调了一下午+一晚上~~~~(>_<)~~~~

上面的写法是不对的,第4行,当区间被包含时,lc,rc 赋不上值,可能会丢失之前的部分信息

改成这样就好啦

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 200001 typedef long long LL; int a[N]; int st[N][],top;
int L[N],R[N]; struct node
{
int x,y;
}A[N]; struct node2
{
int x,yl,yr;
}B[N<<]; LL num; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} int root[][N]; struct TREE
{
int lc[N*],rc[N*];
LL sum[N*];
int tag[N*];
int tot; void insert(int pre,int &k,int l,int r,int opl,int opr)
{
k=++tot;
tag[k]=tag[pre];
sum[k]=sum[pre]+opr-opl+;
lc[k]=lc[pre];
rc[k]=rc[pre];
if(l>=opl && r<=opr)
{
tag[k]++;
return;
}
int mid=l+r>>;
if(opr<=mid) insert(lc[pre],lc[k],l,mid,opl,opr);
else if(opl>mid) insert(rc[pre],rc[k],mid+,r,opl,opr);
else
{
insert(lc[pre],lc[k],l,mid,opl,mid);
insert(rc[pre],rc[k],mid+,r,mid+,opr);
}
} void query(int x,int pre,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr)
{
num+=sum[x]-sum[pre];
return;
}
int mid=l+r>>;
if(opr<=mid)
{
num+=(tag[x]-tag[pre])*(opr-opl+);
query(lc[x],lc[pre],l,mid,opl,opr);
}
else if(opl>mid)
{
num+=(tag[x]-tag[pre])*(opr-opl+);
query(rc[x],rc[pre],mid+,r,opl,opr);
}
else
{
num+=(tag[x]-tag[pre])*(mid-opl+);
query(lc[x],lc[pre],l,mid,opl,mid);
num+=(tag[x]-tag[pre])*(opr-mid);
query(rc[x],rc[pre],mid+,r,mid+,opr);
}
} }tr[]; bool cmp1(node p,node q)
{
return p.x<q.x;
} bool cmp2(node2 p,node2 q)
{
return p.x<q.x;
} int main()
{
//freopen("sf1.in","r",stdin);
//freopen("my.out","w",stdout);
int n,m,p1,p2;
read(n); read(m); read(p1); read(p2);
for(int i=;i<=n;++i) read(a[i]);
st[top][]=n+;
st[top][]=;
for(int i=;i<=n;++i)
{
while(top && a[i]>st[top][]) top--;
L[i]=st[top][];
st[++top][]=a[i];
st[top][]=i;
}
st[top=][]=n+;
st[top][]=n+;
for(int i=n;i;--i)
{
while(top && a[i]>st[top][]) top--;
R[i]=st[top][];
st[++top][]=a[i];
st[top][]=i;
}
int cnt=;
for(int i=;i<=n;++i)
if(L[i] && R[i]<=n)
{
A[++cnt].x=L[i];
A[cnt].y=R[i];
}
sort(A+,A+cnt+,cmp1);
int now=;
for(int i=;i<=cnt;++i)
{
while(now+<A[i].x) root[][now+]=root[][now],now++;
tr[].insert(root[][now],root[][A[i].x],,n,A[i].y,A[i].y);
now=A[i].x;
}
while(now!=n) root[][now+]=root[][now++];
cnt=;
for(int i=;i<=n;++i)
{
if(R[i]!=i+ && L[i])
{
B[++cnt].x=L[i];
B[cnt].yl=i+;
B[cnt].yr=R[i]-;
}
if(L[i]!=i- && R[i]<=n)
{
B[++cnt].x=R[i];
B[cnt].yl=L[i]+;
B[cnt].yr=i-;
}
}
sort(B+,B+cnt+,cmp2);
now=;
for(int i=;i<=cnt;++i)
{
while(now+<B[i].x) root[][now+]=root[][now],now++;
tr[].insert(root[][now],root[][B[i].x],,n,B[i].yl,B[i].yr);
now=B[i].x;
if(tr[].tag[])
{
int as=;
}
}
while(now!=n) root[][now+]=root[][now++];
int l,r;
LL ans;
while(m--)
{
read(l); read(r);
num=;
tr[].query(root[][r],root[][l-],,n,l,r);
ans=num*p1;
num=;
tr[].query(root[][r],root[][l-],,n,l,r);
ans+=num*p2;
ans+=(r-l)*p1;
cout<<ans<<'\n';
}
}

题目背景

影魔,奈文摩尔,据说有着一个诗人的灵魂。 事实上,他吞噬的诗人灵魂早已成千上万。

千百年来,他收集了各式各样的灵魂,包括诗人、 牧师、 帝王、 乞丐、 奴隶、 罪人,当然,还有英雄。

题目描述

每一个灵魂,都有着自己的战斗力,而影魔,靠这些战斗力提升自己的攻击。

奈文摩尔有 n 个灵魂,他们在影魔宽广的体内可以排成一排,从左至右标号 1 到 n。第 i个灵魂的战斗力为 k[i],灵魂们以点对的形式为影魔提供攻击力,对于灵魂对 i, j(i<j)来说,若不存在 ks大于 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]。

输入输出格式

输入格式:

输入文件名为 sf.in。

第一行 n,m,p1,p2

第二行 n 个数: k[1],k[2],…,k[n]

接下来 m 行, 每行两个数 a,b, 表示询问区间[a,b]中的灵魂对会为影魔提供多少攻击力。

输出格式:

输出文件名为 sf.out

共输出 m 行,每行一个答案,依次对应 m 个询问。

输入输出样例

输入样例#1: 复制

10 5 2 3
7 9 5 1 3 10 6 8 2 4
1 7
1 9
1 3
5 9
1 5
输出样例#1: 复制

30
39
4
13
16

说明

30%: 1<= n,m <= 500。

另 30%: p1=2*p2。

100%:1 <= n,m <= 200000; 1 <= p1,p2 <= 1000。

bzoj千题计划196:bzoj4826: [Hnoi2017]影魔的更多相关文章

  1. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  2. bzoj千题计划303:bzoj4827: [Hnoi2017]礼物

    https://www.lydsy.com/JudgeOnline/problem.php?id=4827 式子化简一下,发现最后只跟 Σ xi*yi 有关 第二个序列反转,就可以用FFT优化 注意: ...

  3. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  4. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

  5. bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

  6. bzoj千题计划304:bzoj3676: [Apio2014]回文串(回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3676 回文自动机模板题 4年前的APIO如今竟沦为模板,,,╮(╯▽╰)╭,唉 #include& ...

  7. bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹

    http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...

  8. bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机

    http://www.lydsy.com/JudgeOnline/problem.php?id=4590 二分 这么道水题 没long long WA了两发,没判-1WA了一发,二分写错WA了一发 最 ...

  9. bzoj千题计划250:bzoj3670: [Noi2014]动物园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3670 法一:KMP+st表 抽离nxt数组,构成一棵树 若nxt[i]=j,则i作为j的子节点 那么 ...

随机推荐

  1. Jq_SetTimeOut

    倒计时 59 秒: var t function timedCount() { document.getElementById('txt').value=c ){ c--; }else{ clearT ...

  2. Java 面向对象之构造方法

    01构造方法引入 A:构造方法的引入 在开发中经常需要在创建对象的同时明确对象的属性值,比如员工入职公司就要明确他的姓名.年龄等属性信息. 那么,创建对象就要明确属性值,那怎么解决呢?也就是在创建对象 ...

  3. Apache Ignite 学习笔记(三): Ignite Server和Client节点介绍

    在前两篇文章中,我们把Ignite集群当做一个黑盒子,用二进制包自带的脚本启动Ignite节点后,我们用不同的客户端连接上Ignite进行操作,展示了Ignite作为一个分布式内存缓存,内存数据库的基 ...

  4. DRF框架QQ登录功能

    用户模块---QQ登录 流程图 QQ登录文档:http://wiki.connect.qq.com/%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C_oauth2-0 流程简述 ...

  5. PHP完美分页类

    <?php /** file: page.class.php 完美分页类 Page */ class Page { private $total; //数据表中总记录数 private $lis ...

  6. Ajax实例OR技术原理 转自 (http://blog.csdn.net/evankaka )

    摘要:AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术.AJAX 是一种用于创建快速动态网页的 ...

  7. PAT甲题题解-1031. Hello World for U (20)-字符串处理,水

    #include <iostream> #include <cstdio> #include <algorithm> #include <string.h&g ...

  8. PAT甲题题解-1127. ZigZagging on a Tree (30)-中序、后序建树

    根据中序遍历和前序遍历确定一棵二叉树,然后按“层次遍历”序列输出.输出规则:除根节点外,接下来每层的节点输出顺序是:先从左到右,再从右到左,交替输出 #include <iostream> ...

  9. Sprint report

    Sprint report 一.需求分析:随着在校大学生人数的不断增加,许多高校出现了许多个校区并存的局面,并且校区之间的地理位置跨度非常大,给高校选课带来了很大的不方便,数据处理手工操作,工作量大, ...

  10. 数据平面可编程与SDN关系理解,以及数据平面可编程的理解

    数据平面可编程与SDN关系 狭义 广义 数据平面可编程的理解 狭义 广义