Run ID | 作者 | 问题 | 语言 | 测评结果 | 分数 | 时间 | 内存 | 代码长度 | 提交时间 |
---|---|---|---|---|---|---|---|---|---|
27908 | M0yunAllgor1thm | 【S】T2 区间 | C++ | 运行超时 | 90 | 1151 MS | 253692 KB | 3593 | 2024-03-31 14:00:47 |
#include <bits/stdc++.h> #define LL long long using namespace std; const int MAXN=1e6+5; int N,X,n; LL ans=0; int a[MAXN],a_[MAXN]; set<int>S; vector<int>pos[MAXN]; int st1[MAXN][22],st2[MAXN][22]; int lg[MAXN]; int GetMax(int l,int r) { int x=lg[r-l+1]; return max(st2[l][x],st2[r-(1<<x)+1][x]); } int GetMin(int l,int r) { int x=lg[r-l+1]; return min(st1[l][x],st1[r-(1<<x)+1][x]); } int bound[MAXN],ind=0; int Read() { int x=0; char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=x*10+(ch^48),ch=getchar(); return x; } int LSafe(int L,int R,int x,int y) { int l=L,r=R,res; while(l<=r) { int mid=(l+r)>>1; if(GetMax(mid,R)<=y&&GetMin(mid,R)>=x) { res=mid; r=mid-1; } else l=mid+1; } return res; } int RSafe(int L,int R,int x,int y) { int l=L,r=R,res; while(l<=r) { int mid=(l+r)>>1; if(GetMax(L,mid)<=y&&GetMin(L,mid)>=x) { res=mid; l=mid+1; } else r=mid-1; } return res; } LL Solve(int t) { int v1=a_[t]; int v2=X-v1; ind=0; bound[++ind]=LSafe(1,pos[t][0],v1,v2); for(int i=1;i<pos[t].size();i++) { if(GetMax(pos[t][i-1],pos[t][i])<=v2&&GetMin(pos[t][i-1],pos[t][i])>=v1) continue; // puts("!!!"); bound[++ind]=RSafe(pos[t][i-1],pos[t][i],v1,v2); bound[++ind]=LSafe(pos[t][i-1],pos[t][i],v1,v2); } bound[++ind]=RSafe(pos[t][pos[t].size()-1],N,v1,v2); // for(int i=1;i<=ind;i++) printf("%d ",bound[i]); // puts("<- These are the Bounds"); LL res=0,j=0,k=0; for(int i=1;i<=ind;i+=2) { int L=bound[i],R=bound[i+1]; while(k<pos[t].size()-1&&pos[t][k+1]<=R) k++; // printf("jk%d %d %d %d\n",j,k,L,R); res+=1ll*(R-L+1)*(R-L+2)/2; if(v1==v2) { res-=1ll*(pos[t][j]-L)*(pos[t][j]-L+1)/2; for(int p=j+1;p<=k;p++) { res-=1ll*(pos[t][p]-pos[t][p-1]-1)*(pos[t][p]-pos[t][p-1])/2; } res-=1ll*(R-pos[t][k])*(R-pos[t][k]+1)/2; j=k+1; continue; } int lst1=L-1,lst2=L-1; for(int p=j;p<=k;p++) { int lst3=min(lst1,lst2); if(a[pos[t][p]]==v1) lst1=pos[t][p]; else lst2=pos[t][p]; int pre=L;if(p!=j) pre=pos[t][p-1]+1; // printf("%d %d %d %d %d %d ",p,pos[t][p],lst1,lst2,lst3,pre); if(a[pos[t][p]]==v1) res-=1ll*(lst1-lst2+pre-lst2)*(lst1-pre+1)/2+1ll*(lst2-lst3)*(lst1-pre); else res-=1ll*(lst2-lst1+pre-lst1)*(lst2-pre+1)/2+1ll*(lst1-lst3)*(lst2-pre); // printf(":%lld\n",res); } int pre=pos[t][k]+1; int lst=min(lst1,lst2); res-=1ll*(R-lst+pre-lst)*(R-pre+1)/2; j=k+1; } //printf("Result%d %d %lld\n",v1,v2,res); return res; } int main() { /// freopen("moyun.in","r",stdin); // freopen("moyun.out","w",stdout); scanf("%d %d",&N,&X); for(int i=1;i<=N;i++) { a[i]=Read(); a_[i]=a[i]; } lg[1]=0; for(int i=2;i<=N;i++) lg[i]=lg[i>>1]+1; for(int i=1;i<=N;i++) st1[i][0]=st2[i][0]=a[i]; for(int i=1;i<=lg[N];i++) { for(int j=1;j+(1<<i)-1<=N;j++) { st1[j][i]=min(st1[j][i-1],st1[j+(1<<i-1)][i-1]); st2[j][i]=max(st2[j][i-1],st2[j+(1<<i-1)][i-1]); } } /* for(int i=1;i<=N;i++) { for(int j=0;j<=3;j++) printf("(%d %d) min %d max %d\n",i,j,st1[i][j],st2[i][j]); }*/ sort(a_+1,a_+N+1); n=unique(a_+1,a_+N+1)-a_-1; for(int i=1;i<=N;i++) S.insert(a[i]); for(int i=1;i<=N;i++) { if(S.find(X-a[i])==S.end()) continue; int t=min(a[i],X-a[i]); t=lower_bound(a_+1,a_+N+1,t)-a_; pos[t].push_back(i); //printf("PB%d %d\n",t,i); } for(int i=1;i<=N;i++) { if(pos[i].size()>=1) ans+=Solve(i); } printf("%lld\n",ans); return 0; }