计数方法,博弈论(扫描线,树形SG):HDU 5299 Circles Game

There are n circles on a infinitely large table.With every two circle, either one contains another or isolates from the other.They are never crossed nor tangent.
Alice and Bob are playing a game concerning these circles.They take turn to play,Alice goes first:
1、Pick out a certain circle A,then delete A and every circle that is inside of A.
2、Failling to find a deletable circle within one round will lost the game.
Now,Alice and Bob are both smart guys,who will win the game,output the winner‘s name.

Input

The first line include a positive integer T<=20,indicating the total group number of the statistic.
As for the following T groups of statistic,the first line of every group must include a positive integer n to define the number of the circles.
And the following lines,each line consists of 3 integers x,y and r,stating the coordinate of the circle center and radius of the circle respectively.
n≤20000,|x|≤20000,|y|≤20000,r≤20000。

Output

If Alice won,output “Alice”,else output “Bob”

Sample Input

2
1
0 0 1
6
-100 0 90
-50 0 1
-20 0 1
100 0 90
47 0 1
23 0 1

Sample Output

Alice
Bob  这道题目可以说是模板题……  就是那个SG函数的求法貌似是结论,我不会证明。
 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <set>
 7 using namespace std;
 8 const int N=20010,M=40010;
 9 int cnt,fir[N],to[N],nxt[N];
10 void addedge(int a,int b){
11     nxt[++cnt]=fir[a];
12     to[fir[a]=cnt]=b;
13 }
14 int sqr(int x){return x*x;}
15 int tmp;
16 struct Circle{
17     int x,y,r;
18     Circle(int _=0,int __=0,int ___=0){x=_;y=__;r=___;}
19 }c[N];
20
21 struct Point{
22     int x,id,tp;
23     Point(int _=0,int __=0,int ___=0){x=_;id=__;tp=___;}
24     friend bool operator<(Point a,Point b){
25         double x=c[a.id].y+a.tp*sqrt(sqr(c[a.id].r)-sqr(tmp-c[a.id].x));
26         double y=c[b.id].y+b.tp*sqrt(sqr(c[b.id].r)-sqr(tmp-c[b.id].x));
27         if(x!=y)return x<y;return a.tp<b.tp;
28     }
29 }st[M];
30
31 bool cmp(Point a,Point b){return a.x<b.x;}
32 set<Point>s;set<Point>::iterator it;
33
34 int fa[N],sg[N];
35 int DFS(int x){
36     sg[x]=0;
37     for(int i=fir[x];i;i=nxt[i])
38         sg[x]^=DFS(to[i])+1;
39     return sg[x];
40 }
41
42 void Init(){
43     memset(fir,0,sizeof(fir));
44     cnt=0;
45 }
46 int T,n;
47 int main(){
48     scanf("%d",&T);
49     while(T--){
50         Init();scanf("%d",&n);
51         for(int i=1;i<=n;i++){
52             scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].r);
53             st[2*i-1]=Point(c[i].x-c[i].r,i,-1);
54             st[2*i]=Point(c[i].x+c[i].r,i,1);
55         }
56         sort(st+1,st+2*n+1,cmp);
57         for(int i=1;i<=2*n;i++){
58             Point x=st[i];tmp=x.x;
59             if(x.tp==-1){
60                 it=s.upper_bound(Point(0,x.id,1));
61                 if(it==s.end())addedge(fa[x.id]=0,x.id);
62                 else{
63                     Point y=*it;
64                     if(y.tp==1)
65                         addedge(fa[x.id]=y.id,x.id);
66                     else
67                         addedge(fa[x.id]=fa[y.id],x.id);
68                 }
69                 s.insert(Point(0,x.id,1));
70                 s.insert(Point(0,x.id,-1));
71             }
72             else{
73                 s.erase(Point(0,x.id,1));
74                 s.erase(Point(0,x.id,-1));
75             }
76         }
77         printf(DFS(0)?"Alice\n":"Bob\n");
78     }
79     return 0;
80 }
时间: 2024-08-26 19:08:01

计数方法,博弈论(扫描线,树形SG):HDU 5299 Circles Game的相关文章

hdu 5299 Circles Game(博弈)

题目链接:hdu 5299 Circles Game 每个分离的圆都是单独的游戏,Nim值为该圆嵌套中的圆的Nim和,最后加1. #include <cstdio> #include <cstring> #include <vector> #include <set> #include <algorithm> using namespace std; const int maxn = 20005; typedef long long ll; st

【SG博弈】HDU 5299 Circles Game

通道:http://acm.hdu.edu.cn/showproblem.php?pid=5299 题意:n个不相交相切的圆,每次操作删圆及其内部的圆,不能删者败. 思路:建边,然后树上SG即可. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <set> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int MAX_N =

计数方法(扫描线):JLOI 2016 圆的异或并

Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面 积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑. Input 第一行包含一个正整数N,代表圆的个数.接下来N行,每行3个非负整数x,y,r,表示一个圆心在(x,y),半径为r的 圆.保证|x|,|y|,≤10^8,r>0,N<=200000 Output 仅一行一个整数,表示所有圆的异或面积并除以圆周率Pi的结果. Sample

[多校2015.01.1012 博弈] hdu 5299 Circles Game

题意: 在无限大的平面内给你n个圆,两个圆之间只可能是包含或者相离 A和B每次选择一个圆,删除这个圆连通它所包含的所有圆 谁不能选择圆删除了,谁就输了 思路: 所有圆可以构造成一棵树,然后按树上SG博弈来做就好了. 树的删边游戏 规则如下: 给出一个有 N 个点的树,有一个点作为树的根节点. 游戏者轮流从树中删去边,删去一条边后,不与根节点相连的部分将被移走. 谁无路可走谁输. 我们有如下定理: [定理] 叶子节点的 SG 值为 0; 中间节点的 SG 值为它的所有子节点的 SG 值加 1 后的

HDU 5299 Circles Game

转化为树的删边游戏... 树的删边游戏 规则例如以下:  给出一个有 N 个点的树,有一个点作为树的根节点.  游戏者轮流从树中删去边,删去一条边后,不与根节点相连的 部分将被移走.  谁无路可走谁输. 我们有例如以下定理: [定理] 叶子节点的 SG 值为 0; 中间节点的 SG 值为它的全部子节点的 SG 值加 1 后的异或和. Circles Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/6553

数学基础——基本计数方法

计数方法最基础的两个原理是:加法原理和乘法原理. 容斥原理: 假设一个班里有10个学生喜欢数学,15个学生喜欢语文,21个学生喜欢编程.那么班级总人数: |A∪B∪C| = |A| + |B| + |C| - |A∩B| - |A∩C| - |B∩C| + |A∩B∩C| 一般的,任意多个集合,集合内的元素个数为奇数,前面的符号为正. 问题1:排列问题 n个不同的数,选k个排成1排,有多少种排法. 答案计做p(n,k) = n*(n-1)*(n-2)*...*(n-(k-1)) = n!/(n-

fwt优化+树形DP HDU 5909

1 //fwt优化+树形DP HDU 5909 2 //见官方题解 3 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ 4 5 #include <bits/stdc++.h> 6 // #include <iostream> 7 // #include <cstdio> 8 // #include <cstdlib> 9 // #include <algorithm> 10 // #inc

学习总结--数学.基本计数方法

学习总结--数学.基本计数方法 一.计数方法的原理 1.加法原理:做一件事情有n中办法,第i种办法有pi种执行方案,那么总的解决这件事情的方案数即为p1+p2+p3+...+pn. 2.乘法原理:做一件事情分为n个步骤,第i个步骤的执行方案有pi种,则一共有p1?p2?p3?...?pn种方案解决该问题. 3.容斥原理:一个班级有,集合A的人喜欢数学,集合B的人喜欢英语,结合C的人喜欢语文,那么该班级的人数应该是多少? 如果我们将三个集合的人数相加起来,那么就重复计算了既喜欢数学又喜欢英语的.既

【组合数学】 05 - 经典计数方法

1. 基本计数的母函数 现在来用母函数来求解基本计数问题,母函数既可以完成自动计数,还能表示计数本身,像Stirling数这种就只能用母函数表示.自动计数适用于可以分步的计数问题,并且目标值是每步值之和,这与多项式的运算性质有关. 1.1 组合数和分划数 直观上最符合这一特点的就是模型2,从\(n\)个可区别对象中选出\(m个\).限制第\(k\)个对象被取的次数在集合\(M_k\)中,它被选情况的母函数是\(\sum\limits_{i\in M_k}x^i\),所有元素被选择的情况可以借助母