//快慢指针例题
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+2;
typedef long long ll;
ll a[N];
int main(){
int n,s;cin>>n>>s;
for(int i=1;i<=s;i++)cin>>a[i];
ll l=1,r=0;//i是左指针 j是右指针
ll ans=n+1;
ll sum=0;
for(int i=1,j=0,sum=0;i<=n;i++){//左指针指向第一个数 而右指针指向第一个数的左边
while(i>j||(j+1<=n&&sum<s)){j++;sum+=a[j];}//或者sum+=a[++j];
//如果区间不合法 或者 右指针还有移动空间并且不满足条件的时候移动右指针
if(sum>=s)ans=1ll*min(ans,1ll*(j-i+1));//更新长度
sum-=a[i];//左指针右移带来的影响
}
cout<<(ans==n+1?0:ans);
return 0;
}
AcWing 1236. 递增三元组(蓝桥杯辅导课) - AcWing
//做法3:双指针
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+7;
int a[N],b[N],c[N];
signed main(){
int n;cin>>n;
int ans=0;
for(int i=1;i<=n;i++) scanf("%d", &a[i]);
for(int i=1;i<=n;i++) scanf("%d", &b[i]);
for(int i=1;i<=n;i++) scanf("%d", &c[i]);
sort(a+1,a+n+1);
sort(b+1,b+n+1);
sort(c+1,c+n+1);
int l=1,r=1;//双指针 一个指针用于a数组 一个指针用于b数组
for(int i=1;i<=n;i++){
while(a[l]<b[i]&&l<=n)l++;//l用于记录目前小于b[i]的数的个数
//l肯定是越来越大的 //l肯定是越来越大的 l最后落在了第一个>=b[i]的数上
while(c[r]<=b[i]&&r<=n)r++;//r用来记录小于等于b[i]的数的个数
//r最后落在了一个>b[i]的数上
ans+=(l-1)*(n-r+1);
}
cout<<ans;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N=1007;
//二维前缀和:预处理要与a[i][j]相关联
//预处理:s[i][j]=s[i-1][j]+s[i][j-1]+a[i][j]-s[i-1][j-1] -重复
//实现:(x1,y1)以左上角 (x2,y2)为右上角
//实现: s[x2[y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1][y2] +重复
//一维差分: 预处理b[i]=a[i]-a[i-1] b[i]改变后面的数都改
//二维差分:
//预处理:
//void insert(int x1,int y1,int x2,int y2){ +重复
//b[x1][y1]+=c;
//b[x2+1][y1]-=c;
//b[x1][y2+1]-=c;
//b[x2][y2]+=c;
//实现:
//b[i[j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1] -重复
int a[N][N];
int pre[N][N];
int main(){
int n,m,q;cin>>n>>m>>q;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
pre[i][j]=pre[i-1][j]+pre[i][j-1]+a[i][j]-pre[i-1][j-1];
}
}
while(q--){
int x1,y1,x2,y2;cin>>x1>>y1>>x2>>y2;
cout<<pre[x2][y2]-pre[x1-1][y2]-pre[x2][y1-1]+pre[x1-1][y1-1]<<'\n';
}
return 0;
}
#include <iostream>
using namespace std;
const int N = 1000010;
int a[N], q[N], hh=1, tt = 0;
//q[i]用来存下标
//一般hh设在第一个元素 tt设在hh的前面一位
void getMinWindow(int n, int k) {
for (int i = 1; i <= n; ++i) {
cin >> a[i];
//右端点是i 长度是k 左端点是i-k+1>q[hh]的时候
while(tt>=hh&&i-k+1>q[hh])hh++;//队首元素出队
while (hh <= tt && a[i] <= a[q[tt]]) --tt;//维护队首元素是最小值
q[++tt] = i;
if (i >= k) cout << a[q[hh]] << " ";//形成了一个窗口
}
cout << '\n';
}
void getMaxWindow(int n, int k) {
hh = 1; tt = 0;
for (int i = 1; i <= n; ++i) {
while(tt>=hh&&i-k+1>q[hh])hh++;
while (hh <= tt && a[i] >= a[q[tt]]) --tt;
q[++tt] = i;
if (i >= k) cout << a[q[hh]] << " ";
}
}
int main() {
int n, k;
cin >> n >> k;
getMinWindow(n, k);
getMaxWindow(n, k);
return 0;
}