Portal --> bzoj4826

Solution

  为什么莫名读了很长时间的题。。。== 逐渐不会语文qwq

  貌似这题的做法很多,丢上来的话是因为。。这个化简条件的过程莫名爽哈哈哈哈哈

  注意到因为\(k\)是一个排列,所以不存在等于的情况,那么其实把两个条件都化简一下(其实也不是化简就是用简单一点的语言写出来)就是:

  对于一个点对\((i,j)\)(\(i<j\)),我们用\(mx\)表示\(k[i+1]...k[j-1]\)的最大值,那么如果满足\(mx<k[i]\)&&\(mx<k[j]\)则有\(p1\)的贡献,如果满足\(k[i]<mx<k[j]\)或者\(k[j]<mx<k[i]\)则有\(p2\)的贡献

  至于这个\(k[i]\)和\(k[j]\)谁大谁小的问题。。我们其实完全可以正着统计一次\(k[i]<mx<k[j]\)再把整个数组反过来,然后把询问也反过来再统计一次

  所以现在就变成了求\(mx<k[i]\)&&\(mx<k[j]\)的情况以及\(k[i]<mx<k[j]\)的情况

  再冷静思考一下就会发现,其实也就是说当\(k[i]\)为该区间的最大值的时候,\(k[j]\)为次大值则有\(p1\)的贡献,\(k[j]\)不为次大值的时候则是\(p2\)的贡献,否则(也就是\(k[i]\)不是区间最大值)没有贡献

  那这样一来问题就很好办了

  

  考虑离线做法

​  大体的思路是,我们对于每一个\(k[i]\),将所有满足\([i,j]\)中最大值为\(k[i]\)的\(j\)处的贡献\(+p2\),然后再单独将\(k[j]\)为次大值的\(j\)处的贡献\(-p2+p1\),注意到需要\(+p2\)的位置一定是一个区间,而次大值的那个区间是唯一的,所以我们可以考虑用一棵线段树维护一下区间右端点在每个位置的贡献(其实还是套路想法:固定左端点,考虑右端点在哪些位置有贡献)

​  再具体一点就是,首先预处理出每个\(k[i]\)后面的第一个\(>k[i]\)的位置(记为\(nxt[i]\)),然后我们将所有的询问按照左端点从大到小排序,依次处理,每次将还没有统计的满足\(i>=\)当前询问左端点的区间的贡献进行统计,统计的方式就是线段树对\([i+1,nxt[i]-1]\)区间\(+p2\),再对\(nxt[i]\)这个位置单点\(-p2+p1\),然后对于每个询问\((l,r)\)查询\([l+1,r]\)即可

  然后我们再把数组什么的反过来再重复一遍上面的步骤就好了

  这里有一个比较好玩的地方:就是比如说我们在从左往右处理(就是第一遍计算)的时候,对\(nxt[i]\)这个位置单点\(-p2+p1\)时减去的那个\(p2\)其实应该是在从右往左处理(将数组反过来之后第二遍计算)的时候才会被加到的,相对的第二遍计算的时候减去的那个\(p2\)是在第一次计算的时候加上的,具体的话就是因为。。只有确定了次大值才能比较方便地确定最大值,所以我们对\(nxt[i]\)单点修改的处理其实是将\(k[i]\)看成次大值将\(k[nxt[i]]\)看成最大值,然后计算\([i,nxt[i]]\)这个区间的贡献

  

  如果在线做法的话。。应该可持久化就好了吧qwq

  

​  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=2*(1e5)+10;
int n,m,p1,p2,top;
struct Q{int l,r,id;void rev(){l=n-l+1; r=n-r+1; swap(l,r);}friend bool operator < (Q x,Q y){return x.l>y.l;}
}q[N];
namespace Seg{/*{{{*/const int N=::N*4;int ch[N][2];ll sum[N],tag[N];int n,tot;void pushup(int x,int l,int r){int mid=l+r>>1;sum[x]=sum[ch[x][0]]+tag[ch[x][0]]*(mid-l+1)+sum[ch[x][1]]+tag[ch[x][1]]*(r-mid);}void _build(int x,int l,int r){sum[x]=0; tag[x]=0;if (l==r) return;int mid=l+r>>1;ch[x][0]=++tot; _build(ch[x][0],l,mid);ch[x][1]=++tot; _build(ch[x][1],mid+1,r);}void build(int _n){n=_n; tot=1; _build(1,1,n);}void _update(int x,int l,int r,int lx,int rx,ll delta){if (l<=lx&&rx<=r){tag[x]+=delta; return;}int mid=lx+rx>>1;if (r<=mid) _update(ch[x][0],l,r,lx,mid,delta);else if (l>mid) _update(ch[x][1],l,r,mid+1,rx,delta);else{_update(ch[x][0],l,mid,lx,mid,delta);_update(ch[x][1],mid+1,r,mid+1,rx,delta);}pushup(x,lx,rx);}void update(int l,int r,ll delta){if (l<=r) _update(1,l,r,1,n,delta);}ll _query(int x,int l,int r,int lx,int rx,ll tg){tg+=tag[x];if (l<=lx&&rx<=r) return sum[x]+tg*(r-l+1);int mid=lx+rx>>1;if (r<=mid) return _query(ch[x][0],l,r,lx,mid,tg);else if (l>mid) return _query(ch[x][1],l,r,mid+1,rx,tg);elsereturn _query(ch[x][0],l,mid,lx,mid,tg)+_query(ch[x][1],mid+1,r,mid+1,rx,tg);}ll query(int l,int r){return l<=r?_query(1,l,r,1,n,0):0;}
}/*}}}*/
int nxt[N],st[N],K[N];
ll ans[N];
void get_nxt(){top=0;for (int i=1;i<=n;++i) nxt[i]=n+1;for (int i=1;i<=n;++i){while (top&&K[st[top]]<K[i]) nxt[st[top--]]=i;st[++top]=i;}
}
void solve(){sort(q+1,q+1+m);Seg::build(n+1);int now=n;for (int i=1;i<=m;++i){while (now>=q[i].l){Seg::update(now+1,nxt[now]-1,p2);Seg::update(nxt[now],nxt[now],-p2+p1);--now;}ans[q[i].id]+=Seg::query(q[i].l+1,q[i].r);}
}int main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);
#endifscanf("%d%d%d%d",&n,&m,&p1,&p2);for (int i=1;i<=n;++i) scanf("%d",K+i);for (int i=1;i<=m;++i)scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;get_nxt();solve();reverse(K+1,K+1+n);for (int i=1;i<=m;++i) q[i].rev();get_nxt();solve();for (int i=1;i<=m;++i) printf("%lld\n",ans[i]);
}

转载于:https://www.cnblogs.com/yoyoball/p/9850504.html

【bzoj4826】影魔相关推荐

  1. 【BZOJ4826】[Hnoi2017]影魔 单调栈+扫描线

    [BZOJ4826][Hnoi2017]影魔 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝 ...

  2. 【BZOJ4826】【HNOI2017】影魔(扫描线,单调栈)

    [BZOJ4826][HNOI2017]影魔(扫描线,单调栈) 题面 BZOJ 洛谷 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他 ...

  3. Bzoj4826 [Hnoi2017]影魔

    Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 425  Solved: 244 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实 ...

  4. [题解]bzoj4826 HNOI2017 影魔

    Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...

  5. 刷题总结——影魔(HNOI2017 BZOJ4826 线段树+扫描线)

    题目: Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄 ...

  6. BZOJ4826: [Hnoi2017]影魔

    Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个 ...

  7. 【BZOJ4826】【HNOI2017】影魔

    题意: Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄. ...

  8. [bzoj4826][乱搞][树状数组]影魔

    Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个 ...

  9. [BZOJ4826][HNOI2017]影魔(主席树)

    4826: [Hnoi2017]影魔 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 669  Solved: 384 [Submit][Status ...

最新文章

  1. JDK8之Stream
  2. 安卓手机能用signal吗_现在的安卓手机可以直接更新成鸿蒙系统吗?还是必须购买新的手机?...
  3. 有米android sdk,有米积分墙Android SDK开发者常见问题
  4. 【深度学习】——如何处理输入图像大小不一样的情况
  5. centos 程序 mysql_Centos 源码安装 MySQL
  6. 360浏览器升级_360安全卫士下载|360安全卫士 12.0 最新版
  7. Android 项目必备(二十)-->NFC 的基本使用
  8. 微信小程序上拉触底事件
  9. 计算球体的表面积和体积
  10. uni-app整包更新与热更新方案(安卓和IOS)
  11. Android 项目必备(五)--> Android Studio 制作 App 的 logo 图标
  12. 英语自我介绍资料及范文
  13. 计算机图形学 读书笔记(八) 光线跟踪加速Ray Tracing Acceleration
  14. arm linux kernel 从入口到start_kernel 的代码分析
  15. 批量提取 data/app目录中的apk文件
  16. ssh和scp的使用
  17. linux心跳出血漏洞,heartbleeder 自动检测 OpenSSL 心脏出血漏洞 (附修复指南)
  18. CCF试题 201609-3 炉石传说
  19. 乔布斯经典语录:洗尽铅华的感悟
  20. 关闭windows或者windows server多用户会话

热门文章

  1. 入学年份(year)
  2. ULTRA EDIT -32 之传统正则表达式
  3. 红帽linux5.8系统修复,大神为你分析win7系统VNC客户端连接RedHatLinuxAS5.8的修复方案...
  4. openssh服务和iptabels、firewalld防火墙
  5. VOBSub字幕合并命令行的实现
  6. 米斯特WEB安全攻防白帽子培训视频教程 网站安全检测培训教程 第二期
  7. 正确播放您的图表——有效的数据可视化提示
  8. 我对读计算机软件专业硕士的几点看法
  9. 咔咕(聊天工具)---免费绿色版,图片代替了文字
  10. AuthorizeAttribute 加token验证特性