bzoj 4826: [Hnoi2017]影魔【单调栈+树状数组+扫描线】
2024-08-30 19:31:15
参考: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;
}
最新文章
- Beanstalkd一个高性能分布式内存队列系统
- ExtJS笔记 Store
- BluetoothGatt API
- 适配iOS7uinavigationbar遮挡tableView的问题
- Python-elementTree方法解析xml文件-01
- JavaScript实现的--贪吃蛇
- WebService的简单运用添加删除
- EOS 的世界里可能再也没有小偷了
- shell命令执行hive脚本(hive交互,hive的shell编程)
- javap浅析-书籍第3章的手写稿样稿
- Python学习笔记-转义字符
- ios安装ipa与安卓安装apk
- centos----------防火墙firewalld和iptables
- 【Redis】4、Redis学习资料
- topcoder srm 711 div1 -3
- springboot集成logback日志
- Windows10内置Linux子系统
- 【Android】自己定义控件实现可滑动的开关(switch)
- 如何使用花生壳 发布WCF服务 进行外网访问 z
- 【UVa】1601 The Morning after Halloween(双向bfs)
热门文章
- Flex里监听mouseDownOutside事件解决弹出窗口点击空白关闭功能
- css实现文字渐变
- 配置Python 2.7.1外加环境pywin32-216.win32-py2.7
- Find Minimum in Rotated Sorted Array 旋转数组中找最小值 @LeetCode
- Linux pipe 源代码分析
- Android开发之自己定义Spinner样式的效果实现(源码实现)
- asp.net MVC 中呈现指定区域下的分部视图
- commons-fileupload、smartUpload和commons-net-ftp
- ABAP JSON
- MySql安装与使用图文教程