提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文
前言
起因是前两天打校赛的模拟赛想试试水,结果暴力过16个点,双指针只能过1个点,没错就是第二个点就wa了。翻看记录发现大佬6个月前就a了,所以在大佬的帮助下,有了一点思路。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Ginger的难题I是什么?
是Ginger系列区间操作的一道题,原谅本蒟蒻a不出来
二、题目
不放样例是因为这道题是个思维题,分析样例分析不出来什么我太懒
思路
暴力写的话1e5*1e5必超时,所以很多人可能会尝试双指针,但这是陷阱,即使样例过了也会超时,实际是第2个点wa
所以我们来优化一下,既然是区间操作,必然离不开区间的长度,我们把x出现的长度比作一条线(其中可以包含其他非x的数),我们使用lower-bound找到离l最近的有x的位置L,再找到r左边的有x的位置R,此时可以确定[L,R]一定是x开头,以x结尾,输出相应的长度即可。
上代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int>a[N];
int main()
{
int n;
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
a[x].push_back(i);
}
int m;
cin>>m;
while(m--)
{
int l,r,x;
cin>>l>>r>>x;
int L=lower_bound(a[x].begin(),a[x].end(),l)-a[x].begin();
int R=lower_bound(a[x].begin(),a[x].end(),r)-a[x].begin();
int f=0;
if(L!=a[x].size())
{
if(R==a[x].size())
{
f=a[x].size()-1-L+1;
}
else
{
if(a[x][R]>r)
R--;
f=R-L+1;
}
}
if(f)
cout<<f<<endl;
else
cout<<"666666!"<<endl;
}
cout<<endl;
}
}
总结
第一次写,对于题目可能有理解不到位的地方,如有错误的地方欢迎大佬指正