题意:给定一个长为n的序列和k,定义子串【L,R】(L<=R)合法当:
1.max(a[L]..a[R])-(R-L+1)<=k
2.【L,R】中没有重复的数字
问合法子串的个数
n,k,a[i]<=3e5
思路:对于两个限制分开考虑
对于限制2,预处理出每个位置只考虑限制2左右最多能扩展到哪里
对于限制1,将序列以最大值的位置分治,每次只考虑包含最大值的子串
对于左右两部分其中长度比较小的一部分枚举端点
因为确定了max,另一端合法的范围也可以求出
求最大值位置用RMQ预处理
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 //typedef pair<ll,ll>P; 11 #define N 300010 12 #define M 2000010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pb push_back 17 #define pi acos(-1) 18 #define mem(a,b) memset(a,b,sizeof(a)) 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 21 #define lowbit(x) x&(-x) 22 #define Rand (rand()*(1<<16)+rand()) 23 #define id(x) ((x)<=B?(x):m-n/(x)+1) 24 #define ls p<<1 25 #define rs p<<1|1 26 27 const ll MOD=1e9+7,inv2=(MOD+1)/2; 28 double eps=1e-6; 29 int INF=1e9; 30 int dx[4]={-1,1,0,0}; 31 int dy[4]={0,0,-1,1}; 32 33 int f[N<<1][25],a[N],b[N],l0[N],r0[N],n,k; 34 ll ans; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 int query(int l,int r) 46 { 47 int len=r-l+1; 48 int t=log2(len); 49 int x=f[l][t],y=f[r-(1<<t)+1][t]; 50 if(a[x]>a[y]) return x; 51 return y; 52 } 53 54 void solve(int l,int r) 55 { 56 if(l>r) return; 57 int mid=query(l,r); 58 int len=a[mid]-k; 59 int L,R; 60 if(mid-l<r-mid) 61 { 62 per(i,mid,l) 63 { 64 L=max(mid,len+i-1); 65 R=min(r0[i],r); 66 if(L<=R) ans+=R-L+1; 67 } 68 } 69 else 70 { 71 rep(i,mid,r) 72 { 73 L=max(l,l0[i]); 74 R=min(mid,i-len+1); 75 if(L<=R) ans+=R-L+1; 76 } 77 } 78 solve(l,mid-1); 79 solve(mid+1,r); 80 } 81 82 int main() 83 { 84 //freopen("1.in","r",stdin); 85 //freopen("1.out","w",stdout); 86 int cas=read(); 87 while(cas--) 88 { 89 n=read(),k=read(); 90 rep(i,1,n) a[i]=read(); 91 mem(b,0); 92 l0[0]=0; 93 rep(i,1,n) 94 { 95 l0[i]=max(l0[i-1],b[a[i]]+1); 96 b[a[i]]=i; 97 } 98 rep(i,1,n) b[a[i]]=n+1; 99 r0[n+1]=n+1; 100 per(i,n,1) 101 { 102 r0[i]=min(r0[i+1],b[a[i]]-1); 103 b[a[i]]=i; 104 } 105 rep(i,1,n) f[i][0]=i; 106 for(int i=1;(1<<i)<=n;i++) 107 rep(j,1,n) 108 { 109 int x=f[j][i-1],y=f[j+(1<<(i-1))][i-1]; 110 if(j+(1<<(i-1))>n||a[x]>a[y]) f[j][i]=x; 111 else f[j][i]=y; 112 } 113 ans=0; 114 solve(1,n); 115 printf("%I64d ",ans); 116 } 117 118 return 0; 119 }