2018-2019 ACM-ICPC, Asia Shenyang Regional Contest G(有技巧的暴力)

G. Best ACMer Solves the Hardest Problem

time limit per test

12.0 s

memory limit per test

1024 MB

input

standard input

output

standard output

One day an excellent ACMer will leave the field to face new challenges, just like what the predecessors are doing. Some of them have taken over their family businesses, and some of them are struggling with the edges of unemployment. Some of them have the courage to display themselves and become a professional Ingress player, and some of them are still pushing themselves to limits and try to solve all problems in Project Euler.

But all these destinations are so shallow for Benecol de Cecco, the former king. What he does now is to be the best respondents in StackOverflow. StackOverflow is the largest, most trusted online community for developers to learn, share their programming knowledge, and build their careers.

Today, he notices a question which is posted by Kevin Li, saying: Recently, I implemented an experiment where I need to find all the data records whose Euclidean distances to the query point qq are the same value rr . I tried to use the k-d tree to improve the search efficiency. However, I found that the k-d tree needs to traverse all leaf nodes to return the result, that is, it still needs to compare all dataset to obtain the result.

This question can be formalized to build a database with real-time queries and modifications. In the beginning, suppose we have nn different points in the plane. The ii -th point is located at (xi,yi)(xi,yi) and has a weight wiwi . Then we consider several queries and modifications dynamically given by

  • 1 x y w, to insert a new point at (x,y)(x,y) of weight ww , where we guarantee that before the operation no point was located in the place;
  • 2 x y, to delete the point located at (x,y)(x,y) , where we guarantee that the point existed before the operation;
  • 3 x y k w, for each point whose Euclidean distance to (x,y)(x,y) is k−−√k , to increase its weight by ww ;
  • 4 x y k, to query the sum of weights for all points whose Euclidean distances to (x,y)(x,y) are k−−√k .

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

Input

The input contains several test cases, and the first line contains a positive integer TT indicating the number of test cases which is up to 10001000 .

For each test case, the first line contains two integers nn and mm indicating the initial number of points in the plane and the number of operations respectively, where 1≤n,m≤1051≤n,m≤105 .

Each of the following nn lines contains three integers x,yx,y and ww satisfying 1≤x,y,w≤60001≤x,y,w≤6000 , which describe a point at (x,y)(x,y) of weight ww in the beginning.

Each of the following mm lines contains an operation which can be a query or a modification. These operations are given in the forms described above. To make all xx and yy in operations dynamic, we use lastanslastans to denote the answer to the most recent query and its initial value is zero. For each operation with the values xx and yy in input, their real values should be (((x+lastans)mod6000)+1)(((x+lastans)mod6000)+1) and (((y+lastans)mod6000)+1)(((y+lastans)mod6000)+1) respectively. All coefficients in operations are integers and satisfy 0≤k≤1070≤k≤107 and 1≤x,y,w≤60001≤x,y,w≤6000 .

We guarantee that the sum of nn and the sum of mm in all test cases are no larger than 106106 individually.

 

Output

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

Then for each query, output an integer in a line indicating the answer.

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 xx and yy 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.

 


题目大意 :一个 X, Y轴平面中有若干个带权点, 首先加入 N 个点, M次操作, 操作一 是新加入一个权值为 W的点, 操作2是删除一个坐标为 XI, YI 的点, 操作三是 将与 XI, YI 之间距离 为 根号K 点的权值加上 W, 操作四 是 输出 与 XI, YI

之间距离为根号K的权值之和

思路 : 先预处理, (x1 - x2)^2 + (y1 - y2)^2 = K, (x1 - x2) 与 (y1 - y2) 即为保存的值每次查询的时候, 只要遍历一下该坐标的四个方向(坐标都是整数, 之间距离等于某值最多只有4个点), 然后把存在的点记录下来, 防止重复计算, 用set存

Accepted code

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

#define sc scanf
#define ls rt << 1
#define rs ls | 1
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define MEM(x, b) memset(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int MOD = 6000;
const int MAXN = 1e7 + 100;
const int INF = 0x3f3f3f3f;
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % MOD; b >>= 1; t = (t*t) % MOD; }return r; }

vector <pair <int, int>> f[MAXN];
vector <pair <int, int>> e;
int val[6010][6010], n, m, X, T;
ll last;
int dir[4][2] = { 1, 1, 1, -1, -1, 1, -1, -1 };  // 四个方向

int main()
{
	for (int i = 0; i <= 6000; i++) {
		for (int j = 0; j <= 6000; j++) {
			if (i * i + j * j <= 10000000) f[i * i + j * j].push_back({ i, j });
			else break;
		}
	}  // 预处理
	cin >> T;
	while (T--) {
		sc("%d %d", &n, &m); e.clear(); last = 0;
		for (int i = 0; i < n; i++) {
			int ui, vi, wi; sc("%d %d %d", &ui, &vi, &wi);
			val[ui][vi] = wi;
			e.push_back({ ui, vi });  // 防止初始化超时, 将本次所有点保存
		}
		set <pair <int, int>> st;
		printf("Case #%d:\n", ++X);
		for (int i = 0; i < m; i++) {
			int op, k, xi, yi, wi; st.clear();
			sc("%d %d %d", &op, &xi, &yi);
			xi = (xi + last) % MOD + 1;
			yi = (yi + last) % MOD + 1;
			if (op == 1) {
				sc("%d", &wi); val[xi][yi] = wi;  // 增加
				e.push_back({ xi, yi });
			}
			else if (op == 2) val[xi][yi] = 0;  // 删除
			else if (op == 3) {
				sc("%d %d", &k, &wi);  // 查询
				for (auto it : f[k]) {
					for (int i = 0; i < 4; i++) {
						int xx = xi - it.first * dir[i][0];
						int yy = yi - it.second * dir[i][1];
						if (xx >= 1 && yy >= 1 && xx <= 6000 && yy <= 6000 && val[xx][yy]) st.insert({ xx, yy });
					}
				}
				for (auto it : st) val[it.first][it.second] += wi;
			}
			else {
				sc("%d", &k); last = 0;
				for (auto it : f[k]) {
					for (int i = 0; i < 4; i++) {
						int xx = xi - it.first * dir[i][0]; 
						int yy = yi - it.second * dir[i][1];
						if (xx >= 1 && yy >= 1 && xx <= 6000 && yy <= 6000 && val[xx][yy]) st.insert({ xx, yy });
					}
				}
				for (auto it : st) last += val[it.first][it.second];
				printf("%lld\n", last);
			}
		}
		for (auto it : e) val[it.first][it.second] = 0;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值