G. Best ACMer Solves the Hardest Problem

Problem - G - Codeforces

One day, an outstanding ACMer will leave this field and face new challenges, just like his predecessors did. Some of them have taken over family businesses, and some are struggling on the verge of unemployment. Some people have the courage to show themselves and become professional Ingress players, and some people are still constantly challenging their limits and trying to solve all problems in Project Euler.

However, for former king Benecol de Cecco, all these purposes were too superficial. All he does now is become the best answerer on StackOverflow. StackOverflow is the largest, most trusted online community for developers to learn, share their programming knowledge, and build their careers.

Today, he noticed a problem, posted by Kevin Li, saying: Recently, I implemented an experiment and needed to find all data records whose Euclidean distance to the query point q is the same value r. I try to use kd tree to improve search efficiency. However, I found that kd-tree needs to traverse all leaf nodes to return results, that is, it still needs to compare all data sets to obtain results.

This problem can be formalized by building a database with real-time queries and modifications. First, suppose we have n different points on the plane. The i-th point is located at (xi, yi) and has weight wi. We then consider several queries and modifications given dynamically:

1 xyw, insert a new point (x, y) with weight w. Before the operation, we ensure that no point is at that position; 2 xy, delete the point at (x, y), before the operation, we ensure that the point exists ; 3 xykw, for each point whose Euclidean distance to (x, y) is k−−√, increase its weight by w; 4 xyk, query all the Euclidean distances to (x, y) is the sum of weights of k−−√ points.

Benecol de Cecco said this question was easy and he asked me to share it with you. By the way, the Euclidean distance between two points (x0, y0) and (x1, y1) is equal to (x0−x1)2+(y0−y1)2−−−−−−−−−− −−−−−−−−√.

The input input contains multiple test cases. The first line contains a positive integer T, indicating the number of test cases, up to 1000.

For each test case, the first line contains two integers n and m, representing the initial number of points on the plane and the number of operations, where 1 ≤ n and m ≤ 105.

Each of the following n lines contains three integers x, y and w, satisfying 1 ≤ x, y, w ≤ 6000, describing the point with weight w initially located at (x, y).

Each of the following m lines contains a query or modification operation. These operations are given in the form above. To make x and y dynamic in all operations, we use lastans to represent the answer to the most recent query, with an initial value of zero. For every operation that has values ​​x and y in the input, their actual values ​​should be (((x+lastans)mod6000)+1) and (((y+lastans)mod6000)+1). All coefficients in the operation are integers satisfying 0 ≤ k ≤ 107 and 1 ≤ x, y, w ≤ 6000.

We guarantee that the sum of n and m in all test cases does not exceed 106 respectively.

Output For each test case, first output a line containing "Case #x:" (without quotes), where x is the test case number starting from 1.

Then for each query, output an integer representing the answer in one line.

Example

Input

Copy

1
3 6
2999 3000 1
3001 3000 1
3000 2999 1
1 2999 3000 1
4 2999 2999 1
2 2995 2996
3 2995 2995 1 1
4 2995 2995 1
4 3000 3000 1

Output

Copy

Case #1:
4
6
0

Note

In the sample case, if we ignore the special input format for dynamic x

and y

in operations, here we can show these modifications and queries directly in an offline format as follows:

  • 1 3000 3001 1;
  • 4 3000 3000 1;
  • 2 3000 3001;
  • 3 3000 3000 1 1;
  • 4 3000 3000 1;
  • 4 3007 3007 1.

Solution:
Assume that the distance between points tx, ty and points x, y at this time is square root k

(tx - x)^2 + (ty - y)^2 = k

Let dx = tx - x

dy = you - y

Since the size of k is only 1e7, the sizes of x and y are at most 6000

We can enumerate all dx and dy that satisfy k

Then it meets the conditions

tx = x - dx

you = y - dy

And because the dx and dy we seek are both positive, but they may be negative, there are four situations.

See the code for specific details,

There are many errors caused by re in the game, and it may also be caused by the size exceeding int.

#include<bits/stdc++.h>
using namespace std;
//#define int long long
const int N=1e7 + 10;
typedef pair<int,int> PII;
vector<PII> p[N];
bool vis[7010][7010];
int res[7010][7010];
int dx[4] = {1,1,-1,-1};
int dy[4] = {1,-1,1,-1};
int idx;
void solve()
{
	long long last = 0;
	int n,q;
	cin >> n >> q;
	vector<PII> t; 
	for(int i = 1;i <= n;i++)
	{
		int x,y,w;
		cin >> x >> y >> w;
		t.push_back({x,y});
		vis[x][y] = 1;
		res[x][y] = w;
	}
	cout <<"Case #"<<++idx<<":\n";
	while(q--)
	{
		int op,x,y,k,w;
		cin >> op >> x >> y;
		x = (x + last)%6000 + 1;
		y = (y + last)%6000 + 1;
		t.push_back({x,y});
		
		
		if(op == 1)
		{
			cin >> w;
			vis[x][y] = 1;
			res[x][y] = w;
		}
		else if(op == 2)
		{
			vis[x][y] = 0;
			res[x][y] = 0;
		}
		else if(op == 3)
		{
			cin >> k >> w;
			if(!p[k].size())
			continue;
			set<PII> s;
			for(auto [nx,ny]:p[k])
			{
				for(int j = 0;j < 4;j++)
				{
					int tx = x + dx[j]*nx;
					int ty = y + dy[j]*ny;
					if(tx <= 0||tx > 6000||ty <= 0||ty > 6000)
					continue;
					s.insert({tx,ty});
				}
			}	
			
			
			for(auto[tx,ty]:s)
			{
				if(vis[tx][ty])
				res[tx][ty] += w;
			}
			
			
		}
		else
		{
			cin >> k;
			last = 0;
			if(!p[k].size())
			{
				cout <<last <<"\n";
				continue;
			}
			set<PII> s;
			for(auto [nx,ny]:p[k])
			{
				for(int j = 0;j < 4;j++)
				{
					int tx = x + dx[j]*nx;
					int ty = y + dy[j]*ny;
					if(tx <= 0||tx > 6000||ty <= 0||ty > 6000)
					continue;
					s.insert({tx,ty});
				}
			}			
			
			for(auto[tx,ty]:s)
			{
				if(vis[tx][ty])
				last += res[tx][ty];
			}
			cout << last <<"\n";
		}
	}
	
	for(auto tt:t)
	{
		vis[tt.first][tt.second] = 0;
		res[tt.first][tt.second] = 0;
	}
	t.clear();
}
int main()
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);
//	cout.tie(0);
	for(int i = 0;i <= 6000;i++)
	{
		for(int j = 0;j <= 6000;j++)
		{
			if(i*i + j*j > 1e7)
			{
				break;
			}
			p[i*i + j*j].push_back({i,j});
		}
	}
	int t = 1;
	cin >> t;
	while(t--)
	{
		solve();
	}
}

Guess you like

Origin blog.csdn.net/m0_64158084/article/details/133086382