六 一 欢乐给给赛 T3题解
题目传送门
这道题其实很简单,题如其名,不知道各路dalao为何装弱。
第一种解法:
对于每个查询进行贪心
复杂度:
实际得分:30
代码什么的就不粘了,大家肯定都会写。
第二种解法:
我们考虑到每个数都是正整数,说明以
为lsq序列的第一个元素的话,结尾的元素
的下标
是固定的,也就是可以产生类似树(森林)的结构,我们就可以在树上倍增了。
正解就是队列建树+倍增求解
复杂度
代码非常短
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
inline void read(int &x)
{
int s=0,w=1;
char c=getchar();
while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
while(isdigit(c)){s=(s<<3)+(s<<1)+c-'0',c=getchar();}
x=s*w;
}
inline void write(int x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
const int MAXN=500010;
int fa[MAXN][20],deep[MAXN],x[MAXN],n,K,Q[MAXN],front=1,rear=0,sum[MAXN],T,bin[20];
int main()
{
read(n),read(K);
bin[0]=1;
for(register int i=1;i<=19;i++)bin[i]=bin[i-1]<<1;
for(register int i=1;i<=n;i++)read(x[i]);
for(register int i=1;i<=n;i++)
{
sum[i]=sum[i-1]+x[i];
while(front<=rear&&sum[i]-sum[Q[front]-1]>K)
fa[Q[front++]][0]=i;
Q[++rear]=i;
}
while(front<=rear)
fa[front++][0]=n+1;
for(register int j=1;j<=19;j++)
for(register int i=1;i<=n;i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
read(T);
while(T--)
{
int L,R;
read(L),read(R);
int step=0;
for(register int i=19;~i;i--)
if(fa[L][i]&&fa[L][i]<=R&&L<R)step+=bin[i],L=fa[L][i];
if(L<=R)step++;
write(step),putchar(10);
}
}