没有看懂差分做法,来一个暴力拆式子+数据结构做法。

考虑 ,然后你就发现都可以归约为 ,考虑中间情况,当其为 时候的贡献满足上面的式子,只有为 的时候上面的式子会算错,所以对于一个固定的 ,你考虑其答案为 ,其中 表示有多少个 满足 ,而 很好处理,只需要考虑 即可,考虑把 看成线段 ,显然 不跨过其中点的时候,,反之为 ,又因为 是整数,所以可以考虑中点为 ,接下来思路就比较清晰了,你考虑对于每一对 ,存他们的中点 ,绑定在一起,然后按照中点从大到小排序,对于每个 ,都可以考虑分成两类,因为是从大到小排序,所以一定会有 两个类别,对于 的,肯定取 ,然后你考虑把这里面的 按照 的和 的分开,进行绝对值化简。对于 的,肯定取 ,进行同理的拆分。

然后你发现这样的话复杂度是 ,还是超时,但是你发现,如果我们按照 从小到大处理,那么 的分界线一定会越来越往前,所以我们考虑不用每次都重新记录,直接从上一次没记录完的位置到当前继续记录,先考虑 ,此时的话我们只需要知道小于等于 的个数和他们的和,就可以算出 的同理。

而维护这个东西可以树状数组(一个维护权值,一个维护个数),处理分界线可以二分,所以对于每个 只要算 就可以了,把答案存下来,可以 询问,时间复杂度

更多细节或者不懂的地方可以看代码:

#include<bits/stdc++.h>
#define ll long long
#define db double
#define vec vector
#define pb push_back
#define pll pair<ll,ll>
#define mkp make_pair
#define il inline
#define endl "\n"
using namespace std;
const ll mod=998244353;
const ll inf=1e18;
ll n,q,a[200005],b[200005],cnt[200005],ans[200005];
struct BIT{
	ll c[200005];
	ll lb(ll x){
		return x&(-x);
	}
	void add(ll x,ll y){
		for(ll i=x;i<=n;i+=lb(i)) c[i]+=y;
	}
	ll sum(ll x){
		ll res=0;
		for(ll i=x;i;i-=lb(i)) res+=c[i];
		return res;
	}
}tr1,tr2,tr3,tr4;
struct dat{
	ll a,b,m;
}p[200005];
bool cmp(dat x,dat y){
	return x.m>y.m;
}
ll sa(ll l,ll r){
	if(l>r) return 0;
	return a[r]-a[l-1];
}
ll sb(ll l,ll r){
	if(l>r) return 0;
	return b[r]-b[l-1];
}
ll bs(ll x){
	if(x>p[1].m) return 1;
	if(p[n].m>=x) return n+1;
	ll l=1,r=n,res=0;
	while(l<=r){
		ll md=(l+r)>>1;
		if(p[md].m<x){
			r=md-1,res=md;
		}else{
			l=md+1;
		}
	}
	return res;
}
void solve(){
	cin>>n>>q;
	for(ll i=1;i<=n;i++) tr1.c[i]=tr2.c[i]=tr3.c[i]=tr4.c[i]=cnt[i]=ans[i]=0;
	for(ll i=1;i<=n;i++) cin>>p[i].a>>p[i].b,p[i].m=(p[i].a+p[i].b)>>1,cnt[p[i].a]++,cnt[p[i].b]++,cnt[p[i].a]-=(p[i].a==p[i].b);
	sort(p+1,p+n+1,cmp);ll rt=n+1;
	for(ll i=1;i<=n;i++) tr1.add(p[i].a,1),tr2.add(p[i].a,p[i].a),a[i]=a[i-1]+p[i].a,b[i]=b[i-1]+p[i].b;
	for(ll i=1;i<=n;i++){
		ll pos=bs(i);
		for(ll j=pos;j<rt;j++) tr1.add(p[j].a,-1),tr2.add(p[j].a,-p[j].a),tr3.add(p[j].b,1),tr4.add(p[j].b,p[j].b);
		rt=pos;
		ll c1=tr1.sum(i),s1=tr2.sum(i),c2=tr3.sum(i),s2=tr4.sum(i);
		ll s3=sa(1,pos-1)-s1-(pos-1-c1)*i+c1*i-s1;
		ll s4=sb(pos,n)-s2-(n-pos+1-c2)*i+c2*i-s2;
		ans[i]=s3+s4-n+cnt[i];
	}
	while(q--){
		ll x;cin>>x;
		cout<<ans[x]<<" ";
	}
	cout<<endl;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    ll T;cin>>T;
    while(T--) solve();
    return 0;
}