传送门

我太弱了,只会乱搞,正解是不可能正解的,这辈子不可能写正解的,太蠢了又想不出什么东西,就是乱搞这种东西,才能维持得了做题这样子

考虑将询问离线,按右端点排序,并且预处理出每个位置往前面第一个大于这个数的位置,记为\(fa_i\)

如果加入一个右端点\(i\),那么可以加上贡献的左端点有以下三类

  • 在区间\([fa_i,i)\)中,从\(i-1\)开始一直跳\(fa\),能到达的位置加上p1

  • 在区间\([fa_i,i)\)中,从\(i-1\)开始一直跳\(fa\),不能到达的位置加上p2

  • 在区间\([1,fa_i)\)中,从\(fa_i\)开始一直跳\(fa\),能到达的位置加上p2

看下图把qwq(黑色代表没加上贡献,绿色代表加上p1,红色代表加上p2)

每次移动右端点,对应的询问答案就是询问区间内的权值和

代码极差,慎看

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double using namespace std;
const int N=200000+10,M=240000+10;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
struct sgmtr
{
#define lc (o<<1)
#define rc ((o<<1)|1)
#define mid ((l+r)>>1)
LL a[M<<2];
int lz[M<<2];
il void psup(int o){a[o]=a[lc]+a[rc];}
il void ad(int o,int l,int r,int x){a[o]+=1ll*x*(r-l+1),lz[o]+=x;}
il void psdn(int o,int l,int r)
{
if(lz[o]) ad(lc,l,mid,lz[o]),ad(rc,mid+1,r,lz[o]),lz[o]=0;
}
void modif(int o,int l,int r,int ll,int rr,int x)
{
if(ll<=l&&r<=rr)
{
ad(o,l,r,x);
return;
}
psdn(o,l,r);
if(ll<=mid) modif(lc,l,mid,ll,rr,x);
if(rr>mid) modif(rc,mid+1,r,ll,rr,x);
psup(o);
}
int quer(int o,int l,int r,int ll,int rr)
{
if(ll<=l&&r<=rr) return a[o];
int an=0;
psdn(o,l,r);
if(ll<=mid) an+=quer(lc,l,mid,ll,rr);
if(rr>mid) an+=quer(rc,mid+1,r,ll,rr);
psup(o);
return an;
}
}tr[2];
int to[N],nt[N],hd[N],tot;
il void add(int x,int y){++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;}
int n,m,p1,p2,a[N],fa[N],top[N];
LL an[N];
void dfs(int x,int ntp)
{
top[x]=ntp;
for(int i=hd[x];i;i=nt[i]) dfs(to[i],to[i]==x+1?ntp:to[i]);
}
struct qu
{
int l,r,id;
bool operator < (const qu &bb) const {return r<bb.r;}
}qq[N];
int st[N],tp; int main()
{
n=rd(),m=rd(),p1=rd(),p2=rd();
for(int i=1;i<=n;++i)
{
a[i]=rd();
while(tp&&a[st[tp]]<a[i]) --tp;
fa[i]=st[tp];
st[++tp]=i;
}
for(int i=n;i;--i) add(fa[i],i);
dfs(0,0);
for(int i=1;i<=m;++i) qq[i].l=rd(),qq[i].r=rd(),qq[i].id=i;
sort(qq+1,qq+m+1);
for(int i=1,r=0;i<=m;++i)
{
while(r<qq[i].r)
{
++r;
tr[1].modif(1,0,n,fa[r],r-1,1);
int x=r-1;
while(x)
{
tr[0].modif(1,0,n,top[x],x,1);
tr[1].modif(1,0,n,top[x],x,-1);
x=fa[top[x]];
}
x=fa[fa[r]];
while(x)
{
tr[0].modif(1,0,n,top[x],x,-1);
tr[1].modif(1,0,n,top[x],x,2);
x=fa[top[x]];
}
}
int l=qq[i].l;
an[qq[i].id]=1ll*p1*(tr[0].quer(1,0,n,0,r-1)-tr[0].quer(1,0,n,0,l-1))+1ll*p2*(tr[1].quer(1,0,n,0,r-1)-tr[1].quer(1,0,n,0,l-1));
}
for(int i=1;i<=m;++i) printf("%lld\n",an[i]);
return 0;
}

或者来Orzyyb

luogu P3722 [AH2017/HNOI2017]影魔的更多相关文章

  1. 洛谷P3722 [AH2017/HNOI2017]影魔(线段树)

    题意 题目链接 Sol 题解好神仙啊qwq. 一般看到这种考虑最大值的贡献的题目不难想到单调数据结构 对于本题而言,我们可以预处理出每个位置左边第一个比他大的位置\(l_i\)以及右边第一个比他大的位 ...

  2. P3722 [AH2017/HNOI2017]影魔(单调栈+扫描线+线段树)

    题面传送门 首先我们把这两个贡献翻译成人话: 区间 \([l,r]\) 产生 \(p_1\) 的贡献当且仅当 \(a_l,a_r\) 分别为区间 \([l,r]\) 的最大值和次大值. 区间 \([l ...

  3. [Luogu P3723] [AH2017/HNOI2017]礼物 (FFT 卷积)

    题面 传送门:洛咕 Solution 调得我头大,我好菜啊 好吧,我们来颓柿子吧: 我们可以只旋转其中一个手环.对于亮度的问题,因为可以在两个串上增加亮度,我们也可以看做是可以为负数的. 所以说,我们 ...

  4. [AH2017/HNOI2017]影魔

    嘟嘟嘟 这题真的挺神的,我是真没想出来. 洛谷的第一篇题解说的非常妙,实在是佩服. 就是我们首先预处理出对于第\(i\)个数,在\(i\)左边比第一个比\(i\)大的数\(l_i\),在\(i\)右边 ...

  5. luogu P3726 [AH2017/HNOI2017]抛硬币

    传送门 我是真的弱,看题解都写了半天,,, 这题答案应该是\(\sum_{i=1}^{a}\binom{a}{i}\sum_{j=0}^{min(b,i-1)}\binom{b}{j}\) 上面那个式 ...

  6. luogu P3721 [AH2017/HNOI2017]单旋

    传送门 \(Spaly:\)??? 考虑在暴力模拟的基础上优化 如果要插入一个数,那么根据二叉查找树的性质,这个点一定插在他的前驱的右子树或者是后继的左子树,可以利用set维护当前树里面的数,方便查找 ...

  7. Luogu 3723 [AH2017/HNOI2017]礼物

    BZOJ 4827 $$\sum_{i = 1}^{n}(x_i - y_i + c)^2 = \sum_{i = 1}^{n}(x_i^2 + y_i^2 + c^2 - 2 * x_iy_i + ...

  8. [AH2017/HNOI2017]影魔(主席树+单调栈)

    设\(l[i]\)为i左边第一个比i大的数的下标.\(r[i]\)为i右边第一个比i大的数的下标. 我们把\(p1,p2\)分开考虑. 当产生贡献为\(p1\)时\(i\)和\(j\)一定满足,分别为 ...

  9. LUOGU P3723 [AH2017/HNOI2017]礼物 (fft)

    传送门 解题思路 首先我们设变化量为\(r\),那么最终的答案就可以写成 : \[ ans=min(\sum\limits_{i=1}^n(a_i-b_i+r)^2) \] \[ ans=min(\s ...

随机推荐

  1. N球M盒

    N球,M盒,由于球是否相同,盒是否相同,盒是否可以为空,共2^3=8种: 1.球同,盒同,盒不可以为空Pm(N)--这符号表示部分数为m的N-分拆的个数,m是P的下标,为了好看我将大写的M弄成小写 2 ...

  2. P3373 线段树模板

    好,这是一个线段树模板. #include <cstdio> using namespace std; ; long long int sum[N],tag1[N],tag2[N],mo; ...

  3. Django 配置数据库

    Django提到配置那大多数都是在settings.py配置文件 在配置文件里的 DATABASES 内进行设置 # 数据库配置 DATABASES = { #连接mysql 'default': { ...

  4. C++11并发——多线程条件变量std::condition_variable(四)

    https://www.jianshu.com/p/a31d4fb5594f https://blog.csdn.net/y396397735/article/details/81272752 htt ...

  5. win10开机自启动

    快捷方式复制到win+ R 编辑shell:startup enter后的文件夹中

  6. 转载:C++ 二维数组new

    来源:http://developer.51cto.com/art/201002/183127.htm C++编程语言中有一种叫做new的二维数组,它的应用方式比较灵活,可以有多种方法来帮助我们实现一 ...

  7. Maven Tomcat7+ 实现自动化部署

    首先在Tomcat里配置deploy的用户(tomcat根目录/conf/tomcat-users.xml): <role rolename="tomcat"/> &l ...

  8. nGrinder TestRunnerInsertMysqlSingle.groovy

    s C:\Users\Lindows\workspace\GroovyTest\src\com\iteye\lindows\mysql\TestRunnerInsertMysqlSingle.groo ...

  9. NGUI使用图集的精灵换图片

    创建了一个sprite,选择的是某一个图集下的sprite,现在我想点击它来换图片.前提是你的sprite已经加了UIButton 代码如下: public void OnClick() { if ( ...

  10. 深入浅出 JavaWeb:Servlet必会必知

    一.Web服务器 从事web开发的人,会很清楚一个东西叫HTTP服务器,比如JEE开发—Tomcat,Jetty,.NET开发—ISS等.HTTP服务器是使用 HTTP(超文本传输协议) 与客户机浏览 ...