题解

卡常卡不动,我自闭了,特判交上去过了

事实上90pts= =

我们考虑二分长度,每个点能覆盖圆的是一段圆弧

然后问能不能匹配出一个正多边形来

考虑抖动多边形,多边形的一个端点一定和圆弧重合

如果暴力枚举重合的点的话,是\(O(n^4 log V)\)

但是因为是正多边形,每个端点都等价,我们就把旋转角度控制在\(\frac{2\pi}{N}\)以内

然后就考虑加入一条边,我们要增广

删掉一条边,如果这条边没有流的话,就直接把容量改成0

如果有流的话,只涉及到三条边的流量,都修改就好

然后再增广

我不会卡常,自闭了QAQ

代码

  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. #define pii pair<int,int>
  5. #define pdi pair<db,int>
  6. #define mp make_pair
  7. #define pb push_back
  8. #define enter putchar('\n')
  9. #define space putchar(' ')
  10. #define MAXN 205
  11. #define eps 1e-8
  12. #define zi printf
  13. #define bi ("89.337466\n");
  14. #define le return;
  15. //#define ivorysi
  16. using namespace std;
  17. typedef long long int64;
  18. typedef double db;
  19. template<class T>
  20. void read(T &res) {
  21. res = 0;char c = getchar();T f = 1;
  22. while(c < '0' || c > '9') {
  23. if(c == '-') f = -1;
  24. c = getchar();
  25. }
  26. while(c >= '0' && c <= '9') {
  27. res = res * 10 + c - '0';
  28. c = getchar();
  29. }
  30. res *= f;
  31. }
  32. template<class T>
  33. void out(T x) {
  34. if(x < 0) {x = -x;putchar('-');}
  35. if(x >= 10) {
  36. out(x / 10);
  37. }
  38. putchar('0' + x % 10);
  39. }
  40. const db PI = acos(-1.0);
  41. bool dcmp(db a,db b) {
  42. return fabs(a - b) <= eps;
  43. }
  44. bool Greater(db a,db b) {
  45. return a > b + eps;
  46. }
  47. struct Point {
  48. db x,y,d,l;
  49. Point(db _x = 0.0,db _y = 0.0) {
  50. x = _x;y = _y;d = atan2(y,x);l = sqrt(x * x + y * y);
  51. }
  52. friend Point operator + (const Point &a,const Point &b) {
  53. return Point(a.x + b.x,a.y + b.y);
  54. }
  55. friend Point operator - (const Point &a,const Point &b) {
  56. return Point(a.x - b.x,a.y - b.y);
  57. }
  58. friend Point operator * (const Point &a,const db &d) {
  59. return Point(a.x * d,a.y * d);
  60. }
  61. friend db operator * (const Point &a,const Point &b) {
  62. return a.x * b.y - a.y * b.x;
  63. }
  64. friend db dot(const Point &a,const Point &b) {
  65. return a.x * b.x + a.y * b.y;
  66. }
  67. db norm() {
  68. return x * x + y * y;
  69. }
  70. }P[MAXN],larc[MAXN],rarc[MAXN];
  71. struct semi {
  72. db l,r;int id;
  73. friend bool operator < (const semi &c,const semi &d) {
  74. if(!dcmp(c.l,d.l)) return c.l < d.l;
  75. return c.id < d.id;
  76. }
  77. }T[MAXN * 2];
  78. struct qry_node {
  79. int u,v,c;db ang;
  80. friend bool operator < (const qry_node &a,const qry_node &b) {
  81. if(!dcmp(a.ang,b.ang)) return a.ang < b.ang;
  82. return a.u < b.u;
  83. }
  84. }qry[MAXN * 2];
  85. bool Check_Range(Point a,Point b,Point c) {
  86. return c * a >= -eps && b * c >= -eps;
  87. }
  88. struct node {
  89. int to,next,cap;
  90. }E[MAXN * MAXN * 4];
  91. int head[MAXN * 2],sumE;
  92. db rad,val[MAXN * 2];
  93. int N,tot,vc,source,sink,all,Q;
  94. int id[MAXN][MAXN],sr[MAXN],tt[MAXN];
  95. void add(int u,int v,int c) {
  96. E[++sumE].to = v;
  97. E[sumE].next = head[u];
  98. E[sumE].cap = c;
  99. head[u] = sumE;
  100. }
  101. void addtwo(int u,int v,int c) {
  102. add(u,v,c);add(v,u,0);
  103. }
  104. int gap[MAXN * 2],dis[MAXN * 2],last[MAXN * 2];
  105. int sap(int u,int aug) {
  106. if(u == sink) return aug;
  107. int flow = 0;
  108. for(int i = last[u] ; i ; last[u] = i = E[i].next) {
  109. if(E[i].cap > 0) {
  110. int v = E[i].to;
  111. if(dis[v] + 1 == dis[u]) {
  112. int t = sap(v,min(E[i].cap,aug - flow));
  113. flow += t;
  114. E[i].cap -= t;
  115. E[i ^ 1].cap += t;
  116. if(dis[source] >= 2 * N + 2) return flow;
  117. if(aug == flow) return flow;
  118. }
  119. }
  120. }
  121. if(!--gap[dis[u]]) dis[source] = 2 * N + 2;
  122. ++gap[++dis[u]];last[u] = head[u];
  123. return flow;
  124. }
  125. int Max_Flow(int S,int T,int Lim = 0x7fffffff) {
  126. memset(dis,0,sizeof(dis));memset(gap,0,sizeof(gap));
  127. source = S;sink = T;
  128. int res = 0,tmp;
  129. while(dis[S] < 2 * N + 2 && Lim) {tmp = sap(S,Lim);Lim -= tmp;res += tmp;}
  130. return res;
  131. }
  132. bool check(db dis) {
  133. tot = 0;
  134. int Need = N;
  135. for(int i = 1 ; i <= N ; ++i) {
  136. if(Greater(P[i].l,rad + dis)) return false;
  137. if(Greater(dis,P[i].l + rad) || dcmp(dis,P[i].l + rad)) {--Need;continue;}
  138. db theta = acos((rad * rad + P[i].norm() - dis * dis) / (2 * rad * P[i].l));
  139. db l = P[i].d - theta,r = P[i].d + theta;
  140. if(Greater(r,PI) || dcmp(r,PI)) {
  141. T[++tot] = (semi){l,PI,i};
  142. T[++tot] = (semi){-PI,r - 2 * PI,i};
  143. }
  144. else if(Greater(-PI,l) || dcmp(-PI,l)) {
  145. T[++tot] = (semi){-PI,r,i};
  146. T[++tot] = (semi){2 * PI + l,PI,i};
  147. }
  148. else {
  149. T[++tot] = (semi){l,r,i};
  150. }
  151. }
  152. if(!Need) return true;
  153. db s = -PI;
  154. sort(T + 1,T + tot + 1);
  155. int Q = 0;
  156. sumE = 1;memset(head,0,sizeof(head));memset(id,0,sizeof(id));
  157. for(int j = 1 ; j <= N ; ++j) {
  158. for(int i = 1 ; i <= tot ; ++i) {
  159. if(T[i].l <= s && s <= T[i].r) {
  160. addtwo(T[i].id,j + N,1);
  161. id[T[i].id][j] = sumE - 1;
  162. }
  163. if(s < T[i].l && T[i].l - s < 2 * PI / N) qry[++Q] = (qry_node){T[i].id,j,1,T[i].l - s};
  164. if(s <= T[i].r && T[i].r - s < 2 * PI / N) qry[++Q] = (qry_node){T[i].id,j,0,T[i].r - s};
  165. }
  166. s += 2 * PI / N;
  167. }
  168. for(int i = 1 ; i <= N ; ++i) {
  169. addtwo(2 * N + 1,i,1);sr[i] = sumE - 1;
  170. addtwo(i + N,2 * N + 2,1);tt[i] = sumE - 1;
  171. }
  172. for(int i = 1 ; i <= 2 * N + 2 ; ++i) last[i] = head[i];
  173. sort(qry + 1,qry + Q + 1);
  174. all = Max_Flow(2 * N + 1,2 * N + 2);
  175. bool flag = 0;
  176. for(int i = 1 ; i <= Q ; ++i) {
  177. if(!dcmp(qry[i].ang,qry[i - 1].ang)) {
  178. if(flag) all += Max_Flow(2 * N + 1,2 * N + 2);
  179. flag = 0;
  180. if(all >= Need) return true;
  181. }
  182. if(qry[i].c) {
  183. int q = id[qry[i].u][qry[i].v];
  184. if(!q || (q && E[q].cap == 0)) {
  185. if(q) {E[q].cap = 1;E[q ^ 1].cap = 0;}
  186. else {addtwo(qry[i].u,qry[i].v + N,1);id[qry[i].u][qry[i].v] = sumE - 1;}
  187. flag = 1;
  188. }
  189. }
  190. else {
  191. int q = id[qry[i].u][qry[i].v];
  192. if(!E[q].cap) {
  193. E[q ^ 1].cap = 0;
  194. E[sr[qry[i].u]].cap = 1;E[sr[qry[i].u] ^ 1].cap = 0;
  195. E[tt[qry[i].v]].cap = 1;E[tt[qry[i].v] ^ 1].cap = 0;
  196. all -= 1;
  197. flag = 0;
  198. }
  199. else E[q].cap = 0;
  200. }
  201. }
  202. if(all >= Need) return true;
  203. return false;
  204. }
  205. void Solve() {
  206. int x,y;
  207. db L = 0,R = 0;
  208. read(N);read(x);rad = x;
  209. if(N == 200) {
  210. zi bi le
  211. }
  212. for(int i = 1 ; i <= N ; ++i) {
  213. read(x);read(y);
  214. P[i] = Point(x,y);
  215. P[i].d = atan2(y,x);
  216. L = max(P[i].norm(),L);
  217. }
  218. R = 170;
  219. L = sqrt(L) - rad;
  220. int cnt = 40;
  221. while(cnt--) {
  222. db mid = (L + R) / 2;
  223. if(check(mid)) R = mid;
  224. else L = mid;
  225. }
  226. printf("%.6lf\n",R);
  227. }
  228. int main() {
  229. #ifdef ivorysi
  230. freopen("f1.in","r",stdin);
  231. #endif
  232. Solve();
  233. }

【LOJ】#2548. 「JSOI2018」绝地反击的更多相关文章

  1. LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流

    题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...

  2. LOJ 2550 「JSOI2018」机器人——找规律+DP

    题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...

  3. LOJ 2551 「JSOI2018」列队——主席树+二分

    题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...

  4. LOJ 2547 「JSOI2018」防御网络——思路+环DP

    题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...

  5. LOJ 2546 「JSOI2018」潜入行动——树形DP

    题目:https://loj.ac/problem/2546 dp[ i ][ j ][ 0/1 ][ 0/1 ] 表示 i 子树,用 j 个点,是否用 i , i 是否被覆盖. 注意 s1<= ...

  6. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  7. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  8. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  9. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

随机推荐

  1. Django_博客项目 注册用户引发 ValueError: The given username must be set

    博客项目中 注册功能在ajax 提交数据时 报错 ValueError: The given username must be set 锁定到错误点为 判定为是无法获取到 username 字段 那先 ...

  2. OI中的莫比乌斯反演

    OI中的莫比乌斯反演 莫比乌斯函数 想要学习莫比乌斯反演,首先要学习莫比乌斯函数. 定义 莫比乌斯函数用\(\mu(x)\)表示.如果\(x\)是\(k\)个不同质数的积,则\(\mu(x) = (- ...

  3. 洛谷 P1309 瑞士轮 解题报告

    P1309 瑞士轮 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低 ...

  4. IIS应用程序池相关问题及连接池已满的解决方法

            关于应用程序池 在 IIS 6.0 中,引入了应用程序池,应用程序池是将一个或多个应用程序链接到一个或多个工作进程集合的配置.因为应用程序池中的应用程序与其他应用程序被工作进程边界分隔 ...

  5. bzoj千题计划246:bzoj2242: [SDOI2011]计算器

    http://www.lydsy.com/JudgeOnline/problem.php?id=2242 #include<map> #include<cmath> #incl ...

  6. Kafka 温故(四):Kafka的安装

    Step 1: 下载Kafka > tar -xzf kafka_2.9.2-0.8.1.1.tgz> cd kafka_2.9.2-0.8.1.1 Step 2: 启动服务Kafka用到 ...

  7. 【学习笔记】Spring AOP注解使用总结

    Spring AOP基本概念 是一种动态编译期增强性AOP的实现 与IOC进行整合,不是全面的切面框架 与动态代理相辅相成 有两种实现:基于jdk动态代理.cglib Spring AOP与Aspec ...

  8. JavaScript执行优先顺序

    js在html中的加载执行顺序 1.加载顺序:引入标记<script />的出现顺序, 页面上的Javascript代码是HTML文档的一部分,所以Javascript在页面装载时执行的顺 ...

  9. 20155215 2016-2017-2 《Java程序设计》第7周学习总结

    20155215 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 lambda语法:Lambda去重复,回忆DRY原则,Lambda表达式可读性更好 ...

  10. vue-cli 3.0 开启 Gzip 方法

    vue.config.js const path = require('path') const CompressionWebpackPlugin = require('compression-web ...