QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#403667#5060. Circleskip2004AC ✓448ms4272kbC++203.0kb2024-05-02 17:03:082024-05-02 17:03:10

Judging History

你现在查看的是最新测评结果

  • [2024-05-02 17:03:10]
  • 评测
  • 测评结果:AC
  • 用时:448ms
  • 内存:4272kb
  • [2024-05-02 17:03:08]
  • 提交

answer

#include<bits/stdc++.h>
using std::cin;
using std::cout;
using ll = long long;
using u64 = unsigned long long;
using db = double;
const db eps = 1e-8;
const int N = 2005;

int n, r;
struct func {
	int sgn, x, y;
	db operator () (db p) const {
		return sgn * y + std::sqrt(r * r - (p - x) * (p - x));
	}
	db get(db p) {
		db h = std::sqrt(r * r - p * p);
		return (p * h + r * r * std::atan(p / h)) / 2;
	}
	db inte(db l, db r) {
		return sgn * (r - l) * y + get(r - x) - get(l - x);
	}
};

db lim;
db L, R;
db sgn(db x) {
	return x < -eps ? -1 : x > eps;
}
db integral(db l, db r, std::vector<func> & o) {
	if(o.empty()) return 0;
	db min = 1e18, mid = (l + r) / 2; int id = 0;
	for(int i = 0;i < (int) o.size();++i) {
		db w = o[i](mid);
		if(w < min) {
			min = w;
			id = i;
		}
	}
	if(r - l <= lim) {
		return min * (r - l);
	}
	std::vector<func> L, R;
	db le = l, ri = r;
	func tmp = o[id];
	for(int i = 0;i < (int) o.size();++i) if(i != id) {
		func x = o[i];
		if(x(l) < tmp(l)) L.push_back(x);
		if(x(r) < tmp(r)) R.push_back(x);
		if(x(le) >= tmp(le) && x(ri) >= tmp(ri)) {
			continue;
		}
		if(x(le) < tmp(le)) {
			db l = le, r = mid;
			for(int c = 0;c < 30;++c) {
				db mid = (l + r) / 2;
				if(x(mid) < tmp(mid) - eps) {
					l = mid;
				} else {
					r = mid;
				}
			}
			le = l;
		}
		if(x(ri) < tmp(ri)) {
			db l = mid, r = ri;
			for(int c = 0;c < 30;++c) {
				db mid = (l + r) / 2;
				if(x(mid) < tmp(mid) - eps) {
					r = mid;
				} else {
					l = mid;
				}
			}
			ri = l;
		}
	}
	return tmp.inte(le, ri) + integral(l, le, L) + integral(ri, r, R);
}

int main() {
	std::ios::sync_with_stdio(false), cin.tie(0);
	int T;
	cin >> T;
	for(int i = 0;i < T;++i) {
		cin >> n >> r;
		std::vector<func> a(n);
		L = -1e18, R = 1e18;
		for(func & x : a) {
			cin >> x.x >> x.y;
			x.sgn = 1;
			L = std::max<db>(L, x.x - r);
			R = std::min<db>(R, x.x + r);
		}
		if(n == 1) {
			printf("%.8lf\n", r * r * std::acos(-1));
			continue;
		}
		if(L > R) {
			puts("0");
			continue;
		}
		lim = std::max<db>(R - L, 1) * 1e-6;
		std::vector<func> b = a;
		for(func & x : b) x.sgn = -1;
		db ll = L, rr = R;
		auto eval = [&](db p) {
			db min0 = 1e18;
			db min1 = 1e18;
			for(int i = 0;i < n;++i) {
				min0 = std::min(min0, a[i](p));
				min1 = std::min(min1, b[i](p));
			}
			return min0 + min1;
		};
		for(int i = 0;i < 80;++i) {
			db lm = (ll * 2 + rr) / 3;
			db rm = (ll + rr * 2) / 3;
			if(eval(lm) > eval(rm)) {
				rr = rm;
			} else {
				ll = lm;
			}
		}
		db step = (ll - L);
		for(int i = 0;i < 40;++i) {
			step /= 2;
			if(eval(ll - step) >= 0)
				ll -= step;
		}
		step = R - rr;
		for(int i = 0;i < 40;++i) {
			step /= 2;
			if(eval(rr + step) >= 0)
				rr += step;
		}
		ll += eps;
		rr -= eps;
		db ans = 0;
		if(ll <= rr) {
			static std::mt19937 gen(2);
			shuffle(a.begin(), a.end(), gen);
			shuffle(b.begin(), b.end(), gen);
			ans += integral(ll, rr, a);
			ans += integral(ll, rr, b);
		}
		printf("%.8lf\n", ans);
	}
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 4068kb

input:

3
4 1
0 0
1 0
1 1
0 1
4 1
0 0
1 1
0 2
-1 1
4 100
0 0
1 0
1 1
0 1

output:

0.31514674
0.00000000
31016.92820257

result:

ok 3 numbers

Test #2:

score: 0
Accepted
time: 121ms
memory: 3832kb

input:

200000
1 2
616 2935
1 3
1708 -4771
1 4
4133 2145
1 5
3093 -8563
1 6
-6703 -7258
1 7
-8847 -6629
1 8
-9278 -3604
1 9
3958 -8464
1 10
-7019 4795
1 11
-4181 4366
1 12
-8801 -3294
1 13
-8106 -4512
1 14
-7044 1933
1 15
-5546 -9705
1 16
2755 -6889
1 17
5578 -2779
1 18
3724 -6647
1 19
6530 4628
1 20
-9775 ...

output:

12.56637061
28.27433388
50.26548246
78.53981634
113.09733553
153.93804003
201.06192983
254.46900494
314.15926536
380.13271108
452.38934212
530.92915846
615.75216010
706.85834706
804.24771932
907.92027689
1017.87601976
1134.11494795
1256.63706144
1385.44236023
1520.53084434
1661.90251375
1809.5573684...

result:

ok 200000 numbers

Test #3:

score: 0
Accepted
time: 290ms
memory: 4156kb

input:

49788
1 1
1 1
2 2
-1 -2
2 0
3 7
-1 -2
3 -1
-1 0
3 11
1 -3
4 -2
4 3
4 4
-3 4
-2 1
5 0
3 3
5 3
-6 1
-5 -5
4 -6
5 -2
2 0
6 13
-6 -2
5 -4
6 -4
7 3
5 5
-3 1
7 13
-8 -2
-2 -7
3 -8
8 -8
7 -4
3 -1
-8 4
6 22
-8 -1
-7 -8
-6 -9
7 -8
6 0
1 7
5 29
-9 0
-3 -10
3 -8
5 6
-3 9
1 1
0 1
2 3
0 -1
1 2
3 5
-1 1
1 -1
2 3
...

output:

3.14159265
0.46016018
87.10797263
225.81473906
0.00000000
0
150.18011866
65.33002240
589.96177232
1331.37588799
3.14159265
10.21989512
31.94387253
19.97066140
0
8.49287320
200.61022525
631.16263104
667.62077779
1.95240926
12.56637061
6.19496416
0
19.73478500
70.94389249
258.59351519
122.44499022
20....

result:

ok 49788 numbers

Test #4:

score: 0
Accepted
time: 156ms
memory: 4192kb

input:

236
832 25032
-9981 -8425
-9980 -8477
-9979 -8527
-9975 -8619
-9968 -8777
-9956 -8917
-9948 -8993
-9932 -9112
-9910 -9242
-9907 -9258
-9898 -9298
-9887 -9337
-9857 -9438
-9851 -9457
-9819 -9545
-9812 -9559
-9774 -9627
-9745 -9678
-9729 -9699
-9702 -9734
-9671 -9754
-9637 -9772
-9544 -9819
-9534 -982...

output:

615624863.18774557
30461289.09709729
78003973.01304276
0
0
0
581638153.15033317
0.00000000
0
0.00000000
0
0
0
0
0
1149751764.41279697
0
0
0.00000000
498548613.76492417
0
0
100578150.66456974
0
350695646.48626482
326036462.25307357
0.00000000
0
4868065.86058755
0.00000000
729799.51771165
0
232077640....

result:

ok 236 numbers

Test #5:

score: 0
Accepted
time: 1ms
memory: 4240kb

input:

7
3 6
0 0
11 0
5 8
3 59
0 0
110 0
50 80
6 13
-6 -2
5 -4
6 -4
7 3
5 5
-3 1
3 3
-2 1
-1 0
2 -2
4 1393
985 985
-985 985
-985 -985
985 -985
4 1394
985 985
-985 985
-985 -985
985 -985
4 577
408 408
-408 408
-408 -408
408 -408

output:

0.05806563
0.00780648
150.18011866
2.25077781
0.00000000
3.99617408
0.00000300

result:

ok 7 numbers

Test #6:

score: 0
Accepted
time: 448ms
memory: 4272kb

input:

200
1000 30000
-10000 0
-9999 -141
-9997 -244
-9996 -282
-9995 -316
-9994 -346
-9990 -447
-9988 -489
-9984 -565
-9981 -616
-9980 -632
-9970 -774
-9961 -882
-9956 -937
-9947 -1028
-9934 -1147
-9930 -1181
-9927 -1206
-9919 -1270
-9915 -1301
-9905 -1375
-9890 -1479
-9887 -1499
-9881 -1538
-9875 -1576
-...

output:

1256643426.80736947
1256643862.33246279
1256644141.76160407
1256643490.93239093
1256643524.22921610
1256643848.58104897
1256644473.83831692
1256643581.91923642
1256644479.06879306
1256644159.01183081
1256643552.30200529
1256643648.59611034
1256642981.79741049
1256644149.17051172
1256644318.15673590
...

result:

ok 200 numbers