题解:
将数组分为3部分,左边的A,中间删除B,右边的C,
然后中间删除部分往右移动,左边A增加一个元素,右边C删除一个元素
左边增加一个元素对A,C的影响,右边增加一个元素对A,C的影响想想就清楚了~
然后树状数组就行了~,也是有2种书写方式。
但是这题神TM的卡时间,别直接memset
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define LL long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,sizeof(x)) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef pair<int,int> P; const double eps=1e-9; const int maxn=100050; const int mod=1e9+7; const int INF=1e9; LL read() { LL x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int n,m,a[maxn]; LL c[maxn],b[maxn]; int lowbit(int x){return x&-x;} void add(int x,int v,LL* c){ while(x){ c[x]+=v; x-=lowbit(x); } } LL sum(int x,LL* c){ LL cnt=0; while(x<=n){ cnt+=c[x]; x+=lowbit(x); } return cnt; } int main(){ int T; T=read(); while(T--){ n=read();m=read(); for(int i=1;i<=n;i++) a[i]=read(); memset(b,0,(n+3)*sizeof(LL)); memset(c,0,(n+3)*sizeof(LL)); LL ans=0; for(int i=m+1;i<=n;i++){ ans+=sum(a[i]+1,c); add(a[i],1,c); } LL Min=ans; for(int i=1;i<=n-m;i++){ int l=i,r=i+m; LL tmp=ans; tmp+=sum(a[l]+1,b); add(a[r],-1,c); tmp+=n-m-i-sum(a[l],c); tmp-=sum(a[r]+1,b); tmp-=n-m-i-sum(a[r],c); add(a[l],1,b); Min=min(Min,tmp); ans=tmp; } printf("%lld\n",Min); } return 0; }
时间: 2024-10-11 06:17:56