int n, m; int a[N]; //首先本题就是双指针,只不过维护的是逆序对,比常规双指针增加难度 //我们考虑固定R。对于L,由于是删除区间,左指针右移表示删除区间 //缩小,逆序对数量增加。 //所以我们对于每一个r需要找到极限l,l满足恰好>=k。 //每次移动l都增加了多少逆序对,我们计算具体贡献
} void add(int x, const T &v) { for (int i = x; i <=n-1; i += i & -i) { a[i] = a[i] + v; } } T sum(int x) { T ans{}; for (int i = x; i > 0; i -= i & -i) { ans = ans + a[i]; } return ans; } T rangeSum(int l, int r) {//要传入l-1 //待优化:直接给个vector记录前缀和 return sum(r) - sum(l); } int select(const T &k) {//寻找最后一个使得前缀和小于等于 k 的位置。 int x = 0; T cur{}; for (int i = 1 << std::__lg(n-1); i; i /= 2) {//GCC if (x + i <= n-1 && cur + a[x + i] <= k) { x += i; cur = cur + a[x]; } } return x; } }; void solve(){ cin>>n;cin>>m; for(int i=1;i<=n;i++)cin>>a[i]; Fenwick<int>suf(1e6+1),pre(1e6+1); int sum=0; for(int i=n;i>=1;i--){ suf.add(a[i],1); sum+=suf.sum(a[i]-1); //suf.add(a[i],1); } int ans=0; if(sum>=m)ans++; for(int i=1,j=1;i<=n;i++){ suf.add(a[i],-1); sum-=suf.sum(a[i]-1); sum-=pre.rangeSum(a[i],1000000); //suf.add(a[i],-1); while(j<=i&&sum<m){ pre.add(a[j],1); sum+=suf.sum(a[j]-1); sum+=pre.rangeSum(a[j],1000000); //pre.add(a[j],1); j++; } ans+=i-j+1; } cout<<ans<<endl; }