传送门

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

考虑将询问离线,按右端点排序,并且预处理出每个位置往前面第一个大于这个数的位置,记为\(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. Neovim中提示Error: Required vim compiled with +python

    Neovim在编辑python文件时出现错误提示,如下图 原因 出现该错误的原因说明未安装Python2/3的支持 解决方法 使用包管理器安装Neovim的Python支持python-neovim ...

  2. echarts x轴文字显示不全解决办法

    标题:echarts x轴文字显示不全(xAxis文字倾斜比较全面的3种做法值得推荐):http://blog.csdn.net/kebi007/article/details/68488694

  3. 小Y的炮

    [存代码] #include<bits/stdc++.h> #define N 1000001 #define MAXN 100001 using namespace std; int n ...

  4. (转)多线程——继承Thread 类和实现Runnable 接口的区别

    java中我们想要实现多线程常用的有两种方法,继承Thread 类和实现Runnable 接口,有经验的程序员都会选择实现Runnable接口 ,其主要原因有以下两点: 首先,java只能单继承,因此 ...

  5. fopen() 返回 NULL, 奇葩原因:当前进程打开多个句柄,忘记关闭。(bug)

    今天在测试一个程序的时候,突然第一次弹出错误对话框,提示: 创建新文件失败. fopen() 返回 NULL 我又重启程序测试,还是提示同样的错误. 经过几分钟的检查,发现一个规律:当处理到500多个 ...

  6. key-event

    效果如下 代码如下: 首先看目录 //index.html <!DOCTYPE html> <html lang="zh-CN"> <head> ...

  7. 第九篇-新建文件夹和文本文件mkdirs,createNewFile

    一.新建一个empty activity的项目 二.修改AndroidMainfest.xml,添加用户权限. <?xml version="1.0" encoding=&q ...

  8. CentOS 7 (Linux) 下载百度网盘大文件

    这个方法不仅适合下载 "百度网盘" 中的文件,还可以下载磁链之类的,总之,就是能够加快下载速度的方法. (参考了网上的多篇文章,自行实践,成功下载度盘大文件,并且提升了下载速度) ...

  9. 用python画三角函数

    Pyplot http://www.labri.fr/perso/nrougier/teaching/matplotlib/ pyplot提供了一个方便的matplotlib基于对象库的借口,是模仿了 ...

  10. (栈 注意格式)P1739 表达式括号匹配 洛谷

    题目描述 假设一个表达式有英文字母(小写).运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为表达式的结束符.请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“YES”:否则返 ...