注意a[i]的范围呀。。。
RT,因为把0<=a[i]<=10^5看成1<=a[i]<=10^5痛失60分哪!!!
给定一个长度为的区间,要求求出所有长度为
的连续区间的前
大的和
数据范围:
貌似是目前跑得最快的? 思路就是权值线段树吧,先插入m个数,然后用类似询问第大的过程,如果往右区间走了说明k比所有左区间的数都大,那么我们可以直接加上左区间所有数的和,这个玩意儿我们可以开数组维护
#include<cstdio> #include<cctype> #include<algorithm> #define N 400010 #define maxn 100000 #define lson k<<1 #define rson k<<1|1 using namespace std;int sum[N],n,m,k,a[maxn+10]; long long prosum[N],ans; inline long long read() { char c;int d=1;long long f=0; while(c=getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48; while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48; return d*f; } inline void add(int x,int d,int l=0,int r=maxn,int k=1) { sum[k]+=d;prosum[k]+=x*d; if(l==r) return; int mid=l+r>>1; if(x<=mid) add(x,d,l,mid,lson); else add(x,d,mid+1,r,rson); return; } inline void kth(int p,int l=0,int r=maxn,int k=1) { if(l==r) {ans+=(long long)l*p;return;} int s=sum[lson],mid=l+r>>1; if(s>=p) {kth(p,l,mid,lson);return;} ans+=prosum[lson];kth(p-s,mid+1,r,rson);return; } signed main() { n=read();m=read();k=read(); for(register int i=1;i<=m;i++) a[i]=read(),add(a[i],1); kth(k); for(register int i=m+1;i<=n;i++) { a[i]=read(); add(a[i],1);add(a[i-m],-1);kth(k); } printf("%lld",ans); }