样例没过求调
查看原帖
样例没过求调
588201
hh20080501hh楼主2024/7/11 09:42

输出的答案有负数。

以下标为第一维,权值为 cdq 排序的那一维,删除时间为统计答案的那一维。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5+10;

int n , m;
struct Point
{
	int val , t;
}a[N] , tmp[N] , b[N];
int pos[N];
int ans[N];
int tr[N];

inline int lowbit (int x)
{
	return x&-x;
}

inline void add (int x , int val)
{
	for (int i=x ; i<=n ; i+=lowbit(i))
	{
		tr[i] += val;
	}
}

inline int query (int x)
{
	if (!x) return 0;//可能传0进来
	int res = 0;
	for (int i=x ; i ; i-=lowbit(i))
	{
		res += tr[i];
	}
	return res;
}

void cdq1 (int l , int r)
{
	if(l>=r) return;
	int mid = (l+r)>>1;
	cdq1(l , mid) , cdq1(mid+1 , r);
	int i=mid , j=r , k=r;
	while (i>=l && j>mid)//维护一个递减的序列
	{
		if (a[i].val>a[j].val)
		{
			tmp[k--] = a[j];
			add(a[j].t , 1);
			j--;
		}
		else //找到第一个i<j的地方统计i的答案
		{
			tmp[k--] = a[i];
			ans[a[i].t] += query(n)-query(a[i].t-1);
			i--;
		}
	}
	while (i>=l)
	{
		ans[a[i].t] += query(n)-query(a[i].t-1);
		tmp[k--] = a[i--];
	}
	while (j>mid)
	{
		tmp[k--] = a[j--];
	}
	for (int i=l ; i<=mid ; i++)
	{
		a[i] = tmp[i];
	}
	for (int i=mid+1 ; i<=r ; i++)
	{
		add(a[i].t , -1);
		a[i] = tmp[i];
	}
}

void cdq2 (int l , int r)
{
	if (l>=r) return;
	int mid = (l+r)>>1;
	cdq2(l , mid) , cdq2(mid+1 , r);
	int i = l , j = mid+1 , k = l;
	while (i<=mid && j<=r)
	{
		if (a[i].val>a[j].val)//维护一个升序的序列
		{
			add(a[i].t , 1);
			tmp[k++] = a[i++];
		}
		else //找到第一个i<j的地方统计j的答案
		{
			ans[a[j].t] = query(n)-query(a[j].t-1);
			tmp[k++] = a[j++];
		}
	}
	while (i<=mid)
	{
		tmp[k++] = a[i++];
	}
	while (j<=r)
	{
		ans[a[j].t] += query(n)-query(a[j].t-1);
		tmp[k++] = a[j++];
	}
	for (int i=l ; i<=mid ; i++)
	{
		add(a[i].t , -1) , a[i] = tmp[i];
	}
	for (int i=mid+1 ; i<=r ; i++)
	{
		a[i] = tmp[i];
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	
	cin >> n >> m;
	for (int i=1 ; i<=n ; i++) 
	{
		cin >> a[i].val;
		pos[a[i].val] = i;
	}
	for (int i=1 ; i<=m ; i++)
	{
		int x;
		cin >> x;
		a[pos[x]].t = i;
	}
	for (int i=1 , j=m+1 ; i<=n ; i++)
	{
		if (!a[i].t)
		{
			a[i].t = j;//时间不一样的话不方便统计,全赋成一个值
		}
	}
	for (int i=1 ; i<=n ; i++) b[i] = a[i];
	cdq1(1 , n);
	for (int i=1 ; i<=n ; i++) a[i] = b[i];
	cdq2(1 , n);
	for (int i=1 ; i<=m ; i++)
	{
		cout << ans[i] << '\n';
	}
	return 0;
}
2024/7/11 09:42
加载中...