P3246 [HNOI2016]序列 莫队 + ST表 + 单调栈

传送门

文章目录

  • 题意:
  • 思路:
  • Update

题意:

在这里插入图片描述

思路:

比较神奇的一个题,这里先介绍莫队的离线解法。
不难发现,用莫队来做最大的难点就是在进行区间移动的时候如何快速计算贡献。
比如[l,r]−>[l,r+1][l,r]->[l,r+1][l,r]>[l,r+1]的时候,多出来的区间就是[l,r+1],[l+1,r+1],...,[r+1,r+1][l,r+1],[l+1,r+1],...,[r+1,r+1][l,r+1],[l+1,r+1],...,[r+1,r+1],如何快速计算其贡献呢?
我们考虑维护一个数组f[i]f[i]f[i]表示以iii为结尾的每个后缀的答案,要保证这些后缀都是不交的区间,即后缀的若干区间应该是类似于这种形式[x,i],[y,x−1],...,[1,h−1][x,i],[y,x-1],...,[1,h-1][x,i],[y,x1],...,[1,h1],为了转移方便,考虑记pre[i]pre[i]pre[i]表示左边第一个≤a[i]\le a[i]a[i]的位置,这个用单调栈可以很快维护出来,转移方程:f[i]=(i−pre[i])∗a[i]+f[pre[i]]f[i]=(i-pre[i])*a[i]+f[pre[i]]f[i]=(ipre[i])a[i]+f[pre[i]]
考虑这个怎么用,显然我们不能直接加上f[r+1]f[r+1]f[r+1],因为f[r+1]f[r+1]f[r+1]包含了[1,x],[x+1,y],...,[z+1,r+1][1,x],[x+1,y],...,[z+1,r+1][1,x],[x+1,y],...,[z+1,r+1]这若干段区间的贡献,而我们要算的贡献是[l,r+1][l,r+1][l,r+1]之间的贡献,显然这两个区间是有可能不交的,当然也不能写成f[r+1]−f[l−1]f[r+1]-f[l-1]f[r+1]f[l1]的形式,除非f[r+1]f[r+1]f[r+1]包含的区间中几段拼起来正好有[l,r+1][l,r+1][l,r+1],这样才可以。那么我们往这个思路上靠,是否能找到个位置pospospos,使得[pos+1,r+1][pos+1,r+1][pos+1,r+1]的区间能通过f[r+1]−f[pos]f[r+1]-f[pos]f[r+1]f[pos]直接得到贡献,并且[l,pos][l,pos][l,pos]区间的贡献也能快速计算呢?考虑求fff数组的过程,我们是找左边≤a[i]\le a[i]a[i]的最近的位置,那么我们要是能找到[l,r+1][l,r+1][l,r+1]中的最小值的位置,就可以计算了!显然这个可以STSTST表预处理出来,之后再预处理一下另一边的即可,那么这个题就结束啦,代码还是比较好调的。
实在有点不明白为什么这个题莫队的指针移动顺序对答案有影响,按照莫队的原理来说顺序是随意的,可能这个先加后减是有什么影响,真是为数不多指针移动顺序的有影响的题了。。。等弄懂了再写原因吧。
复杂度O(nlogn+nn)O(nlogn+n\sqrt n)O(nlogn+nn)

Update

在线做法:
继续考虑我们的fff数组,我们还是找一个最小的位置pospospos,让后分成两个区间[l,pos),(pos,r][l,pos),(pos,r][l,pos),(pos,r],当左端点在左边区间,右端点在右边区间的时候,贡献就是(pos−l+1)∗(r−pos+1)∗a[pos](pos-l+1)*(r-pos+1)*a[pos](posl+1)(rpos+1)a[pos],现在就剩左右端点分别在左边和右边区间了,这里只考虑做右端点都在右边的,在左边同理。
考虑如果右端点在rrr,左端点在(pos,r](pos,r](pos,r]的时候的答案为f[r]−f[pos]f[r]-f[pos]f[r]f[pos],右端点在r−1r-1r1,左端点在(pos,r−1](pos,r-1](pos,r1]的时候答案为f[r−1]−f[pos]f[r-1]-f[pos]f[r1]f[pos]…,我们定义sumi=∑j=1ifjsum_i=\sum_{j=1}^if_jsumi=j=1ifj,那么在(pos,r](pos,r](pos,r]的贡献就是gr−gpos−(r−pos)∗fposg_r-g_{pos}-(r-pos)*f_{pos}grgpos(rpos)fpos,右边区间同理。
复杂度O(nlogn)O(nlogn)O(nlogn)

O(nlogn+nn)O(nlogn+n\sqrt n)O(nlogn+nn)

// Problem: P3246 [HNOI2016]序列
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3246
// Memory Limit: 500 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n,m;
int a[N],block;
int stk[N],top,suf[N],pre[N];
LL psum[N],ssum[N];
struct Node {int l,r,id;
}q[N];bool cmp(Node a,Node b)
{int la=(a.l-1)/block+1,lb=(b.l-1)/block+1;return la^lb? la<lb : ((la&1)? a.r>b.r:a.r<b.r);
}int f[N][30];
double len[N];
void init()
{for(int i=1;i<=n;i++) f[i][0]=i;int t=log2(n)+1;for(int j=1;j<t;j++)for(int i=1;i<=n-(1<<j)+1;i++) {if(a[f[i][j-1]]<a[f[i+(1ll<<(j-1))][j-1]]) f[i][j]=f[i][j-1];else if(a[f[i][j-1]]>a[f[i+(1ll<<(j-1))][j-1]]) f[i][j]=f[i+(1ll<<(j-1))][j-1];else if(a[f[i][j-1]]==a[f[i+(1ll<<(j-1))][j-1]]) f[i][j]=max(f[i][j-1],f[i+(1ll<<(j-1))][j-1]);}
}int query(int l,int r) {int t=len[r-l+1];if(a[f[l][t]]<a[f[r-(1<<t)+1][t]]) return f[l][t];else if(a[f[l][t]]>a[f[r-(1<<t)+1][t]]) return f[r-(1<<t)+1][t];return max(f[l][t],f[r-(1<<t)+1][t]);
}LL ans[N],sum;void addl(int l,int r) {int pos=query(l,r);sum+=1ll*(r-pos+1)*a[pos]+ssum[l]-ssum[pos];
}void addr(int l,int r) {int pos=query(l,r);sum+=1ll*(pos-l+1)*a[pos]+psum[r]-psum[pos];
}void dell(int l,int r) {int pos=query(l,r);sum-=1ll*(r-pos+1)*a[pos]+ssum[l]-ssum[pos];
}void delr(int l,int r) {int pos=query(l,r);sum-=1ll*(pos-l+1)*a[pos]+psum[r]-psum[pos];
}int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);cin>>n>>m; block=sqrt(n);for(int i=1;i<=n;i++) len[i]=log2(i);for(int i=1;i<=n;i++) scanf("%d",&a[i]); init();for(int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;sort(q+1,q+1+m,cmp);for(int i=1;i<=n;i++) {while(top&&a[stk[top]]>a[i]) suf[stk[top--]]=i;pre[i]=stk[top]; stk[++top]=i;}while(top) pre[stk[top]]=stk[top-1],suf[stk[top--]]=n+1;for(int i=1;i<=n;i++) psum[i]=1ll*(i-pre[i])*a[i]+psum[pre[i]];for(int i=n;i>=1;i--) ssum[i]=1ll*(suf[i]-i)*a[i]+ssum[suf[i]];int l=1,r=0;for(int i=1;i<=m;i++) {int lx=q[i].l,rx=q[i].r;while(l>lx) addl(--l,r);while(r<rx) addr(l,++r);while(r>rx) delr(l,r--);while(l<lx) dell(l++,r);ans[q[i].id]=sum;}for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);return 0;
}

O(nlogn)O(nlogn)O(nlogn)

// Problem: P3246 [HNOI2016]序列
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3246
// Memory Limit: 500 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n,m;
int a[N],block;
int stk[N],top;
LL suf[N],pre[N];
LL psum[N],ssum[N];int f[N][30];
double len[N];
void init()
{for(int i=1;i<=n;i++) f[i][0]=i;int t=log2(n)+1;for(int j=1;j<t;j++)for(int i=1;i<=n-(1<<j)+1;i++) {if(a[f[i][j-1]]<a[f[i+(1ll<<(j-1))][j-1]]) f[i][j]=f[i][j-1];else if(a[f[i][j-1]]>a[f[i+(1ll<<(j-1))][j-1]]) f[i][j]=f[i+(1ll<<(j-1))][j-1];else if(a[f[i][j-1]]==a[f[i+(1ll<<(j-1))][j-1]]) f[i][j]=max(f[i][j-1],f[i+(1ll<<(j-1))][j-1]);}
}int query(int l,int r) {int t=len[r-l+1];if(a[f[l][t]]<a[f[r-(1<<t)+1][t]]) return f[l][t];else if(a[f[l][t]]>a[f[r-(1<<t)+1][t]]) return f[r-(1<<t)+1][t];return max(f[l][t],f[r-(1<<t)+1][t]);
}int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);cin>>n>>m; for(int i=1;i<=n;i++) len[i]=log2(i);for(int i=1;i<=n;i++) scanf("%d",&a[i]); init();for(int i=1;i<=n;i++) {while(top&&a[stk[top]]>a[i]) suf[stk[top--]]=i;pre[i]=stk[top]; stk[++top]=i;}while(top) pre[stk[top]]=stk[top-1],suf[stk[top--]]=n+1;for(int i=1;i<=n;i++) psum[i]=1ll*(i-pre[i])*a[i]+psum[pre[i]];for(int i=n;i>=1;i--) ssum[i]=1ll*(suf[i]-i)*a[i]+ssum[suf[i]];for(int i=1;i<=n;i++) pre[i]=pre[i-1]+psum[i];for(int i=n;i>=1;i--) suf[i]=suf[i+1]+ssum[i];while(m--) {int l,r; scanf("%d%d",&l,&r);int pos=query(l,r);LL ans=1ll*(pos-l+1)*(r-pos+1)*a[pos];ans+=pre[r]-pre[pos]-psum[pos]*(r-pos);ans+=suf[l]-suf[pos]-ssum[pos]*(pos-l);printf("%lld\n",ans);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF 渲染原理

对于开发者来说&#xff0c;WPF 中最主要的知识点就是渲染&#xff0c;因为 WPF 是一个界面框架。想用一篇博客就能告诉大家完整的 WPF 渲染原理是不可能的。本文向大家介绍从开发者执行绘图指令到在屏幕显示的过程。本文是从一个全局的角度来看渲染的过程&#xff0c;在本文之…

HDU - 6989 Didn‘t I Say to Make My Abilities Average in the Next Life?! 莫队/单调栈 + 线段树/ST表在线

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 考虑将贡献分开来算&#xff0c;先计算最大值&#xff0c;再算个最小值&#xff0c;之后答案就是((maxmin)/2)/(len∗(len1)/2)((maxmin)/2)/(len*(len1)/2)((maxmin)/2)/(len∗(len1)/2)。…

ASP.NET Core 中的管道机制

首先&#xff0c;很感谢在上篇文章 C# 管道式编程 中给我有小额捐助和点赞的朋友们&#xff0c;感谢你们的支持与肯定。希望我的每一次分享都能让彼此获得一些收获&#xff0c;当然如果我有些地方叙述的不正确或不当&#xff0c;还请不客气的指出。好了&#xff0c;下面进入正文…

微软宣布SQL Server 2019免费支持Java

在 2018 年 9 月的时候&#xff0c;微软就宣布与领先的 Java 开源贡献者和发行商 Azul Systems 建立新的合作伙伴关系。这一关系允许所有 Azure 客户在微软和 Azul 联合提供的支持下&#xff0c;免费使用 Azul 的 Zulu for Azure-Enterprise Java 发行版 。最近&#xff0c;微软…

P4231 三步必杀 二次差分

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 考虑给[2,6][2,6][2,6]加上s2,e10s2,e10s2,e10的等差数列&#xff0c;变成2,4,6,8,102,4,6,8,102,4,6,8,10&#xff0c;考虑差分数组2,2,2,2,2,−102,2,2,2,2,-102,2,2,2,2,−10&#xff0…

创新的迷思——2019 Microsoft Hackathon 苏州站回顾

每年&#xff0c;微软在7月份都会在内部举办一次黑客松&#xff08;Hachathon&#xff09;活动&#xff0c;所有的员工&#xff0c;包括实习生都可以自由组队参赛&#xff0c;在为期一周的时间内完成构想、设计和开发的一系列过程&#xff0c;并且在最后一天进行项目路演和评选…

P4062 [Code+#1]Yazid 的新生舞会 树状数组维护三阶差分

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个序列aaa&#xff0c;让你求有多少个子区间满足存在一个数是这个区间的绝对众数&#xff0c;绝对众数指该数在区间内出现的次数严格大于r−l12\frac{r-l1}{2}2r−l1​。 n≤5e5,0≤ai≤n−1n\le5e5,0…

一句话概括4本管理著作

之前618活动的时候买了不少书&#xff0c;最近一段时间集中看了四本管理相关的书籍&#xff0c;收获颇丰。在这里分享给大家。如果你不是管理者也没关系&#xff0c;可以换个视角来看看管理者眼中的世界&#xff0c;毕竟&#xff0c;“赤兔马”也需要让“伯乐”看到才行嘛。虽然…

[译].Net中的内存-什么分配在了哪里

原文链接&#xff1a;https://jonskeet.uk/csharp/memory.html人们在理解值类型和引用类型之间的差异时因为“值类型在栈上分配&#xff0c;引用类型在堆上分配”这句话造成了很多混乱。这完全是不对的&#xff0c;本文试图澄清这个问题。变量中有什么&#xff1f;理解.NET中内…

上车时机已到--.NETCore是适应时代发展的雄鹰利剑

要起飞了.NET Core 3.0-prevew7&#xff1a;https://dotnet.microsoft.com/download/dotnet-core/3.0随着 .NET Core 3.0-prevew7 的发布&#xff0c;开源社区的一支重要力量重要即将起飞&#xff1b;官方指出&#xff0c;该预览版为可能为最终版本&#xff0c;在很长一段时间内…

HDU - 7028 Decomposition 无向完全图构造欧拉回路

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一张无向完全图&#xff0c;让你构造kkk个长度分别为lil_ili​的路径&#xff0c;这些路径不相交&#xff0c;且∑lin∗(n−1)2\sum l_i\frac{n*(n-1)}{2}∑li​2n∗(n−1)​。 n≤1000,nmod21n\le1000,…

「Azure」数据分析师有理由爱Azure之二-立即申请帐号开始学习之旅

目前关于Azure的学习资料不多&#xff0c;除了官方的文档和Microsoft Learn频道外&#xff0c;几乎没有什么中文性资料可学习&#xff0c;就算有&#xff0c;也是以IT的思维方式来展开介绍&#xff0c;对没有IT背景的数据分析师来说&#xff0c;非常难于适应。本篇给大家带来一…

矩阵快速幂的最简单用法

矩阵快速幂 链接&#xff1a;https://ac.nowcoder.com/acm/contest/1168/K 来源&#xff1a;牛客网 题目描述 这个勇者明明超强却过分慎重&#xff0c;勇者龙宫院圣哉与n名冒险者一起去讨伐神秘魔物&#xff0c;龙宫院圣哉十分谨慎&#xff0c;他只会在最后一刻出手&#xff…

DevOps案例研究|史上最能“拜客户教”的公司,是如何做到持续交付的?(第1趴)...

内容来源&#xff1a;DevOps案例深度研究 –Amazon持续交付之道战队&#xff08;本文只展示部分PPT及研究成果&#xff0c;更多细节请关注案例分享会&#xff0c;及本公众号。&#xff09;本案例内容贡献者&#xff1a;单冰 (Topic Leader)、 赵栋、梁兴龙、李杰、毛艳清、牛恒…

P2261 [CQOI2007]余数求和 整除分块

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; n,k≤1e9n,k\le1e9n,k≤1e9 思路&#xff1a; 考虑转换式子&#xff0c;∑i1nkmodi∑i1n(k−⌊ki⌋∗i)n∗k−∑i1n⌊ki⌋∗i\sum_{i1}^{n}k\bmod i\sum_{i1}^n(k-\left \lfloor \frac{k}{i} \right \rfloo…

背包问题——第一篇

一&#xff0c;01背包 最简单也是最经典的背包问题。 首先我们知道背包问题是一种d问题&#xff0c;最重要的就是要去找到他的状态转移方程。而在01背包中转移方程就比较简单了&#xff0c;这里用一个二维数组进行标表示。 ans[i][j]max(ans[i-1][j],ans[i-1][j-v[i]w[i]); 在…

小白开学Asp.Net Core 《十》

小白开学Asp.Net Core 《十》 — — Session、Cookie、Cache&#xff08;老生常谈&#xff09;一、背景在常谈Session和Cookie之前我们先来简单的了解下Http&#xff08;可以说这是必须的&#xff0c;默认大家都了解&#xff09;总结一句话&#xff1a;HTTP是一种无状态的协议&…

P3935 Calculating 整除分块

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 我们设s(x)∑i1nf(x)s(x)\sum_{i1}^nf(x)s(x)∑i1n​f(x)&#xff0c;那么答案就是s(r)−s(l−1)s(r)-s(l-1)s(r)−s(l−1)。 容易发现&#xff0c;我们要求的f(x)f(x)f(x)实际上就是xxx的…

Sticks-hdu-1455深度搜索dfs

Sticks 题目传送门。 题目大意是&#xff0c;给你一个数字n代表总共的棍子数量&#xff0c;要做的就是&#xff0c;把这几根棍子拼成长度相同的棍子&#xff0c;并且让所拼成的棍子的长度尽可能地小&#xff0c;也就是拼成的棍子的数量尽可能的多。 在这里很简单的想到要给棍…

gRPC in ASP.NET Core 3.0 -- Protocol Buffer(1)

开发环境&#xff1a;IDE: VSCodeVSCode的扩展插件&#xff1a;vscode-proto3和Clang-Format这两个扩展Windows还需要安装Clang&#xff0c;Windows 64位系统的地址如下&#xff1a;Clang for Windows (64-bit)(http://llvm.org/releases/3.7.0/LLVM-3.7.0-win64.exe)&#xff…