HDU - 1166 Enemy Formation (CDQ Divide and Conquer Solution)

This problem can be solved by line segment tree, tree array, and modified team Mo. Here we use CDQ divide and conquer to solve it, as learning CDQ divide and conquer!


It may be a little difficult to learn CDQ division at the beginning, but when you do the questions, you will feel it if you experience it again.

Most importantly, CDQ is still used for dimensionality reduction. Many blogs have talked about it. In fact, the divide-and-conquer solution for inverse ordinal numbers is the core problem of CDQ divide-and-conquer. When divide and conquer is divided into left and right intervals, how does the left interval affect the right interval? As long as we solve this problem, we can use CDQ to divide and conquer.

For example, in this question, we split all queries into query prefix sums. Obviously, when the modified coordinates are smaller than the query coordinates, this modification will affect the subsequent query, so I will modify it, and then do that query. For specifics, look at the code to experience.


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

struct Query
{
	int type;
	int id;
	int val;
	bool operator<(const Query &b) const
	{
		if (id == b.id)
			return type < b.type;
		return id < b.id;
	}
} q[200005];
int qn;

int years[200005];
int an;

Query tmp[200005];
void CDQ(int l, int r)
{
	if (r <= l + 1)
		return;
	int m = (l + r) / 2;
	CDQ (l, m);
	CDQ(m, r);
	int sum = 0;
	int i = l, j = m, k = 0;
	while (i < m && j < r)
	{
		if (q[i] < q[j])
		{
			if (q[i].type == 1)
				sum += q[i].val;
			tmp[k++] = q[i++];
		}
		else
		{
			if (q[j].type == 2)
				ans[q[j].val] -= sum;
			else if (q[j].type == 3)
				ans[q[j].val] += sum;
			tmp[k++] = q[j++];
		}
	}

	while (i < m)
		tmp[k++] = q[i++];
	while (j < r)
	{
		if (q[j].type == 2)
			ans[q[j].val] -= sum;
		else if (q[j].type == 3)
			ans[q[j].val] += sum;
		tmp[k++] = q[j++];
	}
	for (int i = 0; i < k; i++)
		q[i + l] = tmp[i];
}

char str[200];
intmain()
{
	int T;
	scanf("%d", &T);
	int N;
	int ttt=1;
	while (T--)
	{
		memset(ans,0,sizeof(ans));
		qn=0;
		an=0;
		printf("Case %d:\n",ttt++);
		scanf("%d", &N);
		for (int i = 1; i <= N; i++)
		{
			q[qn].id = i;
			q[qn].type = 1;
			scanf("%d", &q[qn].val);
			qn++;
		}

		while(1){
			
			scanf("%s", str);
			if(str[0]=='E')
				break;
			if(str[0]=='A'){
				q[qn].type = 1;
				scanf("%d%d", &q[qn].id, &q[qn].val);
			}
			else if(str[0]=='S'){
				q[qn].type = 1;
				scanf("%d%d", &q[qn].id, &q[qn].val);
				q[qn].val=-q[qn].val;
			}
				
			else if(str[0]=='Q')
			{
				int l, r;
				scanf("%d%d", &l, &r);
				q[qn].type=2;
				q[qn].id = l - 1;
				q[qn].val = an;
				qn++;
				q[qn].type = 3;
				q[qn].id = r;
				q[qn].val = an;
				an++;
			}
			qn++;
		}


		CDQ(0, qn);
		for (int i = 0; i < an; i++)
			printf("%d\n", ans[i]);
			
	}

	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325990518&siteId=291194637