参考:https://www.cnblogs.com/lcf-2000/p/6789680.html

这是一个相对码量少的做法,用到了区间修改区间查询的树状数组,详见:www.cnblogs.com/lcf-2000/p/5866170.html#3830447

枚举最大值a[i],找到l[i],r[i]是左边最后一个比它大的和右边第一个比它大的,考虑贡献:

p1:每次询问要先加上(r-l)*p1是点对相邻,然后对r[i]有p1贡献的左端点是l[i]

p2:对l[i]有贡献的是(i+1,r[i]-1),对r[i]有贡献的是(l[i]+1,i-1)

离线排序+扫描线做就行,情况都要考虑到。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=400005;
int n,m,p1,p2,a[N],s[N],top,r[N],l[N],tot;
long long ans[N],c1[N],c2[N];
struct qwe
{
int l,r,x,b,z;
qwe(int L=0,int R=0,int X=0,int B=0,int Z=0)
{
l=L,r=R,x=X,b=B,z=Z;
}
}b[N],c[N];
bool cmp(const qwe &a,const qwe &b)
{
return a.x<b.x;
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
int lb(int x)
{
return x&(-x);
}
void add(int x,int v)
{
if(!x)
return;
for(int i=x;i<=n;i+=lb(i))
c1[i]+=v,c2[i]+=1ll*x*v;
}
long long ques(int x)
{
long long re=0;
for(int i=x;i>0;i-=lb(i))
re+=(x+1)*c1[i]-c2[i];
return re;
}
int main()
{
n=read(),m=read(),p1=read(),p2=read();
a[0]=a[n+1]=n+1;
s[top=1]=0;
for(int i=1;i<=n+1;i++)
{
if(i<=n)
a[i]=read();
while(a[s[top]]<a[i])
r[s[top--]]=i;
l[i]=s[top];
s[++top]=i;
}
for(int i=1;i<=m;i++)
{
int l=read(),r=read();
ans[i]+=(r-l)*p1;//相邻两个点产生的贡献
b[i]=qwe(l,r,l-1,i,-1);
b[i+m]=qwe(l,r,r,i,1);
}
sort(b+1,b+1+2*m,cmp);
for(int i=1;i<=n;i++)
{
if(l[i]&&r[i]<=n)
c[++tot]=qwe(l[i],l[i],r[i],0,p1);
if(l[i]&&r[i]>i+1)
c[++tot]=qwe(i+1,r[i]-1,l[i],0,p2);
if(r[i]<=n&&i>l[i]+1)
c[++tot]=qwe(l[i]+1,i-1,r[i],0,p2);
}
sort(c+1,c+1+tot,cmp);
int w1=1,w2=1;
while(!b[w1].x)
w1++;
for(int i=1;w1<=m*2&&i<=n;i++)//扫描线
{
while(w2<=tot&&c[w2].x==i)
{
add(c[w2].r+1,-c[w2].z);
add(c[w2].l,c[w2].z);
w2++;
}
while(w1<=2*m&&b[w1].x==i)
{
ans[b[w1].b]+=b[w1].z*(ques(b[w1].r)-ques(b[w1].l-1));
w1++;
}
}
for(int i=1;i<=m;i++)
printf("%lld\n",ans[i]);
return 0;
}

最新文章

  1. Beanstalkd一个高性能分布式内存队列系统
  2. ExtJS笔记 Store
  3. BluetoothGatt API
  4. 适配iOS7uinavigationbar遮挡tableView的问题
  5. Python-elementTree方法解析xml文件-01
  6. JavaScript实现的--贪吃蛇
  7. WebService的简单运用添加删除
  8. EOS 的世界里可能再也没有小偷了
  9. shell命令执行hive脚本(hive交互,hive的shell编程)
  10. javap浅析-书籍第3章的手写稿样稿
  11. Python学习笔记-转义字符
  12. ios安装ipa与安卓安装apk
  13. centos----------防火墙firewalld和iptables
  14. 【Redis】4、Redis学习资料
  15. topcoder srm 711 div1 -3
  16. springboot集成logback日志
  17. Windows10内置Linux子系统
  18. 【Android】自己定义控件实现可滑动的开关(switch)
  19. 如何使用花生壳 发布WCF服务 进行外网访问 z
  20. 【UVa】1601 The Morning after Halloween(双向bfs)

热门文章

  1. Flex里监听mouseDownOutside事件解决弹出窗口点击空白关闭功能
  2. css实现文字渐变
  3. 配置Python 2.7.1外加环境pywin32-216.win32-py2.7
  4. Find Minimum in Rotated Sorted Array 旋转数组中找最小值 @LeetCode
  5. Linux pipe 源代码分析
  6. Android开发之自己定义Spinner样式的效果实现(源码实现)
  7. asp.net MVC 中呈现指定区域下的分部视图
  8. commons-fileupload、smartUpload和commons-net-ftp
  9. ABAP JSON
  10. MySql安装与使用图文教程