感觉双指针的主要思想就是就是摒弃显然已经被排除的一段
统计和为kkk的子矩阵,枚举区间右端点rrr,当[l,r][l,r][l,r]子段和超过k,lk,lk,l右移
因为显然[l,r]不能包含在满足要求的矩阵中(太大了),要缩小,摒弃掉l列以左的所有
双指针分别是区间左右端点[l,r][l,r][l,r],区间数res+=(r−l+1)res+=(r-l+1)res+=(r−l+1)
这里要求是区间中不含重复元素,当出现重复元素(此时出现在下标i,上一次mp[a[i]])mp[a[i]])mp[a[i]])
要摒弃掉mp[a[i]]以左的元素,有个注意点,
#include
using namespace std;
#define int long long int
mapmp;
const int N=1e5+10;
int n;
int a[N];
signed main(){cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}int res=0;// 1 2 3 4int last=0;for(int i=1;i<=n;i++){if(mp[a[i]]){ if(mp[a[i]]>last)last=mp[a[i]];//2 12 3 12 3 2 6 9 遍历到最后一个2,last=第一个3}res+=(i-last);//last是上一段满足条件的区间段的最后一个元素mp[a[i]]=i;} cout<
以下思路是对的,但是求(last,r]这段的子区间数量 方式不对,也不知道为啥不对,给的两个样例也都通过了
不过双指针求区间数量的常见做法都是 每次遍历(一个端点,左指针或右指针)时,利用左右指针相减
#include
using namespace std;
#define int long long int
mapmp;
const int N=1e5+10;
int n;
int a[N];
signed main(){cin>>n;for(int i=1;i<=n;i++){cin>>a[i];}int len=0;int res=n;int last=0;for(int i=1;i<=n;i++){if(mp[a[i]]==0||mp[a[i]]len++;mp[a[i]]=i;}else{len=i-mp[a[i]];// 1 2 3 4res+=(1+len)*len/2-len;last=mp[a[i]];mp[a[i]]=i;}}res+=(1+len)*len/2-len;cout<

上一篇:宁德时代:公司在全固态电池上持续投入,2027年有望实现小批量生产 宁德时代固态电池新生产线 宁德时代2020储能动力电池
下一篇:从营业员做到商业集团掌门人,徐恭藻卸任董事长,“80后”女儿接任 利群集团总裁徐恭藻简介 利群集团董事长徐恭藻生平经历