CCPC-Wannafly Winter Camp Day5 (Div2, onsite)

 

 

Replay:


 

Dup4:

  • 时间复杂度算不对? 一点点思路不经过验证就激动的要死? 浪费自己一个小时还浪费别人一个小时?
  • 对1e3不敏感? 1e3 * 1e3是多少? 模拟建边跑dp不写非要写个大模拟?
  • 看到数据结构就高兴的要死? 没细想? 没发现性质? 

 X:

  • 日常语文差, 导致计算几何死都写不对  读题要细致啊!
  • 感觉状态还可以?只是计算几何写太久了, 人都懵了

 

 

 

 

A:Cactus Draw

Solved.

按照BFS序以及深度排

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int maxn = 1e4 + 10;
 6 
 7 struct Edge{
 8     int to, nxt;
 9     Edge(){}
10     Edge(int to, int nxt) :to(to), nxt(nxt){}
11 }edge[maxn << 1];
12 
13 struct node{
14     int x, y;
15     node(){}
16     node(int x, int y):x(x), y(y){}
17 }ans[maxn];
18 
19 int n, m;
20 int head[maxn], tot;
21 int vis[maxn];
22 int level[maxn];
23 
24 void Init()
25 {
26     tot = 0;
27     memset(vis, 0, sizeof vis);
28     memset(level, 0, sizeof level);
29     memset(head, -1, sizeof head);
30 }
31 
32 void addedge(int u,int v)
33 {
34     edge[tot] = Edge(v, head[u]); head[u] = tot++;
35     edge[tot] = Edge(u, head[v]); head[v] = tot++;
36 }
37 
38 void BFS(int root)
39 {
40     queue<int>q;
41     q.push(root);
42     vis[root] = 1;
43     ans[root] = node(vis[root], ++level[vis[root]]);
44     while(!q.empty())
45     {
46         int u = q.front();
47         q.pop();
48         for(int i = head[u]; ~i; i = edge[i].nxt)
49         {
50             int v = edge[i].to;
51             if(!vis[v])
52             {
53                 vis[v] = vis[u] + 1;
54                 ans[v] = node(vis[v], ++level[vis[v]]);
55                 q.push(v);
56             }
57         }
58     }
59 }
60 
61 int main()
62 {
63     while(~scanf("%d %d", &n, &m))
64     {
65         Init();
66         for(int i = 1, u, v; i <= m; ++i)
67         {
68             scanf("%d %d", &u, &v);
69             addedge(u, v);
70         }
71         BFS(1);
72         for(int i= 1 ; i <= n; ++i)
73         {
74             printf("%d %d\n", ans[i].x, ans[i].y);
75         }
76     }
77     return 0;
78 }
View Code

 

C:Division

Solved.

每次取最大进行操作,堆维护

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 100010
 6 int n, k;
 7 
 8 int main()
 9 {
10     while (scanf("%d%d", &n, &k) != EOF)
11     {
12         priority_queue <int> pq;
13         ll res = 0;
14         for (int i = 1, a; i <= n; ++i)
15         {
16             scanf("%d", &a);
17             pq.push(a);
18         }
19         for (int i = 1; i <= k; ++i)
20         {
21             int top = pq.top(); pq.pop();
22             pq.push(top / 2);
23         }
24         while (!pq.empty())
25         {
26             res += pq.top();
27             pq.pop();
28         }
29         printf("%lld\n", res);
30     }
31     return 0;
32 }
View Code

 

D:doppelblock

unsolved.

搜索。

增加剪枝:当剩余的数字小于x之间的数字时,回溯掉即可。

还有一条剪枝可以先处理x的位置在填数字(未写)

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 typedef long long ll;
  6 
  7 const ll MOD = 1e9 + 7;
  8 
  9 const int maxn = 1e2 + 10;
 10 
 11 int n;
 12 int sum = 0;
 13 int r[maxn], c[maxn];
 14 int left_r[maxn], left_c[maxn];
 15 int mid_r[maxn], mid_c[maxn];
 16 int right_r[maxn], right_c[maxn];
 17 int cnt_r[maxn], cnt_c[maxn];
 18 int vis_r[maxn][maxn], vis_c[maxn][maxn];
 19 char mp[maxn][maxn];
 20 
 21 void Init()
 22 {
 23     memset(left_r, 0, sizeof left_r);
 24     memset(left_c, 0, sizeof left_c);
 25 
 26     memset(mid_r, 0, sizeof mid_r);
 27     memset(mid_c, 0, sizeof mid_c);
 28 
 29     memset(right_r, 0, sizeof right_r);
 30     memset(right_c, 0, sizeof right_c);
 31 
 32     memset(cnt_r, 0, sizeof cnt_r);
 33     memset(cnt_c, 0, sizeof cnt_c);
 34 
 35     memset(vis_r, 0, sizeof vis_r);
 36     memset(vis_c, 0, sizeof vis_c);
 37 }
 38 
 39 bool DFS(int x, int y)
 40 {
 41     if (x == n && y == n + 1) return true;
 42     if (y == n + 1)
 43     {
 44         if (cnt_r[x] != 2) return false;
 45         else return DFS(x + 1, 1);
 46     }
 47 
 48     if (cnt_r[x] == 0 && cnt_c[y] == 0)
 49     {
 50         mp[x][y] = 'X';
 51         cnt_r[x]++;
 52         cnt_c[y]++;
 53         if (DFS(x, y + 1)) return true;
 54         cnt_r[x]--;
 55         cnt_c[y]--;
 56     }
 57 
 58     if (cnt_r[x] == 0 && (cnt_c[y] == 1 && mid_c[y] == c[y]))
 59     {
 60         mp[x][y] = 'X';
 61         cnt_r[x]++;
 62         cnt_c[y]++;
 63         if (DFS(x, y + 1)) return true;
 64         cnt_r[x]--;
 65         cnt_c[y]--;
 66     }
 67 
 68     if (cnt_c[y] == 0 && (cnt_r[x] == 1 && mid_r[x] == r[x]))
 69     {
 70         mp[x][y] = 'X';
 71         cnt_r[x]++;
 72         cnt_c[y]++;
 73         if (DFS(x, y + 1)) return true;
 74         cnt_r[x]--;
 75         cnt_c[y]--;
 76     }
 77 
 78     if ((cnt_r[x] == 1 && mid_r[x] == r[x]) && (cnt_c[y] == 1 && mid_c[y] == c[y]))
 79     {
 80         mp[x][y] = 'X';
 81         cnt_r[x]++;
 82         cnt_c[y]++;
 83         if (DFS(x, y + 1)) return true;
 84         cnt_r[x]--;
 85         cnt_c[y]--;
 86     }
 87 
 88 
 89 
 90     for (int i = 1; i <= n - 2; ++i)
 91     {
 92         if (vis_r[x][i] || vis_c[y][i]) continue;
 93         if (cnt_r[x] == 0)
 94         {
 95             if (sum - (left_r[x] + i) < r[x]) continue;
 96         }
 97         else if (cnt_r[x] == 1)
 98         {
 99             if (mid_r[x] + i > r[x]) continue;
100         }
101 
102         if (cnt_c[y] == 0)
103         {
104             if (sum - (left_c[y] + i) < c[y]) continue;
105         }
106         else if (cnt_c[y] == 1)
107         {
108             if (mid_c[y] + i > c[y]) continue;
109         }
110 
111         if (cnt_r[x] == 0) left_r[x] += i;
112         else if (cnt_r[x] == 1) mid_r[x] += i;
113         else if (cnt_r[x] == 2) right_r[x] += i;
114 
115         if (cnt_c[y] == 0) left_c[y] += i;
116         else if (cnt_c[y] == 1) mid_c[y] += i;
117         else if (cnt_c[y] == 2) right_c[y] += i;
118 
119         vis_r[x][i]++;
120         vis_c[y][i]++;
121 
122         mp[x][y] = i + '0';
123         if (DFS(x, y + 1)) return true;
124 
125         if (cnt_r[x] == 0) left_r[x] -= i;
126         else if (cnt_r[x] == 1) mid_r[x] -= i;
127         else if (cnt_r[x] == 2) right_r[x] -= i;
128 
129         if (cnt_c[y] == 0) left_c[y] -= i;
130         else if (cnt_c[y] == 1) mid_c[y] -= i;
131         else if (cnt_c[y] == 2) right_c[y] -= i;
132 
133         vis_r[x][i]--;
134         vis_c[y][i]--;
135     }
136 
137     return false;
138 }
139 
140 void RUN()
141 {
142     int t;
143     int flag = 0;
144     scanf("%d", &t);
145     while (t--)
146     {
147         if (flag++) printf("\n");
148         Init();
149         scanf("%d", &n);
150         for (int i = 1; i <= n; ++i) scanf("%d", r + i);
151         for (int i = 1; i <= n; ++i) scanf("%d", c + i);
152         sum = (n - 2) * (n - 1) / 2;
153         DFS(1, 1);
154         for (int i = 1; i <= n; ++i)
155         {
156             for (int j = 1; j <= n; ++j)
157             {
158                 printf("%c", mp[i][j]);
159             }
160             puts("");
161         }
162     }
163 }
164 
165 int main()
166 {
167 #ifdef LOCAL_JUDGE
168     freopen("Text.txt", "r", stdin);
169 #endif // LOCAL_JUDGE
170 
171     RUN();
172 
173 #ifdef LOCAL_JUDGE
174     fclose(stdin);
175 #endif // LOCAL_JUDGE
176     return 0;
177 }
View Code

 

E:Fast Kronecker Transform

Upsolved.

将同样的数放在一起,如果同样的数字小于$10000,直接暴力$

否则做NTT

$因为模数是998244353,可以直接做,做FFT可能有精度问题$

$F(n) = \sum f(t) \cdot g(n - t)$

$f(t) = t   当  a_t = x$

$g(t) = t 当 b_t = x$

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define db long double
  5 #define ll long long
  6 #define N 400010
  7 #define S 10010
  8 const ll MOD = (ll)998244353;
  9 int n, m, a[N], b[N], c[N];
 10 vector <int> l[N], r[N];
 11 ll ans[N];
 12 
 13 void Hash()
 14 {
 15     c[0] = 0;
 16     for (int i = 0; i <= n; ++i) c[++c[0]] = a[i];
 17     for (int i = 0; i <= m; ++i) c[++c[0]] = b[i];
 18     sort(c + 1, c + 1 + c[0]);
 19     c[0] = unique(c + 1, c + 1 + c[0]) - c - 1;
 20     for (int i = 0; i <= n; ++i) a[i] = lower_bound(c + 1, c + 1 + c[0], a[i]) - c;
 21     for (int i = 0; i <= m; ++i) b[i] = lower_bound(c + 1, c + 1 + c[0], b[i]) - c;   
 22 }
 23 
 24 ll qmod(ll base, ll n)
 25 {
 26     ll res = 1;
 27     while (n)
 28     {
 29         if (n & 1) res = (res * base) % MOD;
 30         base = base * base % MOD;
 31         n >>= 1;
 32     }
 33     return res;
 34 }
 35 
 36 int x1[N], x2[N];
 37 void ntt(int *a, int len, int f)
 38 {
 39     int i, j = 0, t, k;
 40     for (int i = 1; i < len - 1; ++i)
 41     {
 42         for (t = len; j ^= t >>= 1, ~j & t;);
 43         if (i < j) swap(a[i], a[j]);
 44     }
 45     for (int i = 1; i < len; i <<= 1)
 46     {
 47         t = i << 1;
 48         int wn = qmod(3, (MOD - 1) / t);
 49         for (int j = 0; j < len; j += t)
 50         {
 51             int w = 1;
 52             for (k = 0; k < i; ++k, w = 1ll * w * wn % MOD)
 53             {
 54                 int x = a[j + k], y = 1ll * w * a[j + k + i] % MOD;
 55                 a[j + k] = (x + y) % MOD, a[j + k + i] = (x - y + MOD) % MOD;
 56             }
 57         }
 58     }
 59     if (f == -1)
 60     {
 61         reverse(a + 1, a + len);
 62         int inv = qmod(len, MOD - 2);
 63         for (int i = 0; i < len; ++i) a[i] = 1ll * a[i] * inv % MOD;
 64     }
 65 }
 66 
 67 int main()
 68 {
 69     while (scanf("%d%d", &n, &m) != EOF)
 70     {
 71         for (int i = 0; i <= n; ++i) scanf("%d", a + i);
 72         for (int i = 0; i <= m; ++i) scanf("%d", b + i); Hash();
 73         for (int i = 0; i <= n; ++i) l[a[i]].push_back(i);
 74         for (int i = 0; i <= m; ++i) r[b[i]].push_back(i);
 75         int len1 = n + 1, len2 = m + 1, len = 1;
 76         while (len < (len1 + len2)) len <<= 1;
 77         memset(ans, 0, sizeof ans);
 78         for (int i = 1; i <= n + m + 5; ++i) 
 79         {
 80             if (l[i].size() + r[i].size() < S)
 81             {
 82                 for (auto u : l[i]) for (auto v : r[i])
 83                     ans[u + v] = (ans[u + v] + (1ll * u * v) % MOD) % MOD; 
 84             }
 85             else
 86             {
 87                 for (int j = 0; j < len; ++j) x1[j] = 0;
 88                 for (int j = 0; j < len; ++j) x2[j] = 0;
 89                 for (auto x : l[i]) x1[x] = x;
 90                 for (auto x : r[i]) x2[x] = x; 
 91                 ntt(x1, len, 1); 
 92                 ntt(x2, len, 1);
 93                 for (int j = 0; j < len; ++j)
 94                     x1[j] = 1ll * x1[j] * x2[j] % MOD; 
 95                 ntt(x1, len, -1); 
 96                 for (int j = 0; j <= n + m; ++j) 
 97                     ans[j] = (ans[j] + x1[j]) % MOD;
 98             }
 99         }
100         for (int i = 0; i <= n + m; ++i) printf("%lld%c", ans[i] % MOD, " \n"[i == n + m]);
101     }
102     return 0;
103 }
View Code

 

 

F:Kropki

Solved.

 习惯性记忆化搜索(实际上是个状压dp)

$dp[S][i]表示S状态下i作为最后一个出现的状态, dp下去即可$

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 const ll MOD = 1e9 + 7;
 8 
 9 int n;
10 ll dp[1 << 16][20];
11 char str[20];
12 
13 ll DFS(int S, int last, int dep)
14 {
15     if(dep == n) 
16     {
17         return 1ll;
18     }
19     if(dp[S][last] != -1) return dp[S][last];
20     ll res = 0;
21     for(int i = 1; i <= n; ++i)
22     {
23         if(S & (1 << (i - 1))) continue;
24         if(dep)
25         {
26             if(str[dep] == '1')
27             {
28                 if(i != last * 2 && i * 2 != last) continue;
29             }
30             if(str[dep] == '0')
31             {
32                 if(i == last * 2 || i * 2 == last) continue;
33             }
34         }
35         ll tmp = DFS((S | (1 << (i - 1))), i, dep + 1);
36         res = (res + tmp) % MOD;
37     }
38     dp[S][last] = res;
39     return res;
40 }
41 
42 int main()
43 {
44     while(~scanf("%d", &n))
45     {
46         scanf("%s", str + 1);
47         memset(dp, -1, sizeof dp);
48         ll ans = DFS(0, 0, 0);
49         printf("%lld\n", ans);
50     }
51     return 0;
52 }
View Code

 

 

H:Nested Tree

Solved.

点数只有$10^6,建边树形DP$

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 const ll MOD = (ll)1e9 + 7;
 8 const int maxn = 1e6 + 10;
 9 
10 struct Edge{
11     int to, nxt;
12     Edge(){}
13     Edge(int to, int nxt):to(to), nxt(nxt){}    
14 }edge[maxn << 1];
15 
16 int n, m;
17 int head[maxn], tot;
18 ll son[maxn];
19 ll ans;
20 
21 
22 void Init()
23 {
24     ans = 0;
25     tot = 0;
26     memset(head, -1, sizeof head);
27 }
28 
29 void addedge(int u,int v)
30 {
31     edge[tot] = Edge(v, head[u]); head[u] = tot++;
32     edge[tot] = Edge(u, head[v]); head[v] = tot++;
33 }
34 
35 void DFS(int u, int fa)
36 {
37     son[u] = 1;
38     for(int i = head[u]; ~i; i = edge[i].nxt) 
39     {
40         int v = edge[i].to;
41         if(v == fa) continue;
42         DFS(v, u);
43         son[u] += son[v];
44         ans = (ans + (son[v] * (n - son[v]) % MOD) % MOD) % MOD;
45     }
46 }
47 
48 int main()
49 {
50     while(~scanf("%d %d", &n, &m))
51     {
52         Init();
53         for(int i = 1, u, v; i < n; ++i)
54         {
55             scanf("%d %d", &u, &v);
56             for(int j = 1; j <= m; ++j)
57             {
58                 addedge((j - 1) * n + u, (j - 1) * n + v);
59             }
60         }
61         for(int i = 1, a, b, u, v; i < m; ++i)
62         {
63             scanf("%d %d %d %d", &a ,&b, &u, &v);
64             addedge((a - 1) * n + u, (b - 1) * n + v);
65         }
66         n *= m;
67         DFS(1, -1);
68         printf("%lld\n", ans);
69     }
70     return 0;
71 }
View Code

 

I:Sorting

Upsolved.

将数分为两类,一类是$<= x, 二类是> x $

同一类的数在怎么操作其相对位置都是不变的

那么我们只需要知道前缀区间内有多少个一类数,有多少个二类数

再用前缀和维护同一类数的和即可

 

$2、3操作用线段树维护即可,用0, 1分别表示一类数$

每次操作相当于将前面连续一段赋值为$0/1  后面连续一段赋值为1/0$

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define ll long long
  5 #define N 200010
  6 int n, q, x, a[N];
  7 ll sum[2][N];
  8 
  9 namespace SEG
 10 {
 11     int lazy[N << 2], v[N << 2];
 12     void pushdown(int id, int l, int r, int mid)
 13     {
 14         if (lazy[id] == -1) return;
 15         lazy[id << 1] = lazy[id];
 16         lazy[id << 1 | 1] = lazy[id];
 17         v[id << 1] = lazy[id] * (mid - l + 1);
 18         v[id << 1 | 1] = lazy[id] * (r - mid);
 19         lazy[id] = -1;
 20     }
 21     void pushup(int id) { v[id] = v[id << 1] + v[id << 1 | 1]; }
 22     void build(int id, int l, int r) 
 23     {
 24         lazy[id] = -1, v[id] = 0;
 25         if (l == r)
 26         {
 27             v[id] = a[l] > x;
 28             return;
 29         }
 30         int mid = (l + r) >> 1;
 31         build(id << 1, l, mid);
 32         build(id << 1 | 1, mid + 1, r);
 33         pushup(id);
 34     }
 35     void update(int id, int l, int r, int ql, int qr, int val)
 36     {
 37         if (l >= ql && r <= qr)
 38         {
 39             lazy[id] = val;
 40             v[id] = val * (r - l + 1);
 41             return;
 42         }
 43         int mid = (l + r) >> 1;
 44         pushdown(id, l, r, mid);
 45         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
 46         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
 47         pushup(id);
 48     }
 49     int query(int id, int l, int r, int ql, int qr)
 50     {
 51         if (r < l) return 0;
 52         if (l >= ql && r <= qr) return v[id];
 53         int mid = (l + r) >> 1;
 54         pushdown(id, l, r, mid);
 55         int res = 0;
 56         if (ql <= mid) res += query(id << 1, l, mid, ql, qr);
 57         if (qr > mid) res += query(id << 1 | 1, mid + 1, r, ql, qr);
 58         return res;
 59     }
 60 }
 61 
 62 ll que(int r)
 63 {
 64     if (r < 1) return 0;
 65     int a = SEG::query(1, 1, n, 1, r);
 66     int b = r - a;
 67     //cout << a << " " << b << endl;
 68     //cout << sum[1][a] << " " << sum[0][b] << endl;
 69     return (a ? sum[1][a] : 0) + (b ? sum[0][b] : 0);  
 70 }
 71 
 72 int main()
 73 {
 74     while (scanf("%d%d%d", &n, &q, &x) != EOF)
 75     {
 76         sum[0][0] = 0, sum[1][0] = 0;
 77         for (int i = 1; i <= n; ++i) 
 78         {
 79             scanf("%d", a + i);
 80             if (a[i] <= x) sum[0][++sum[0][0]] = a[i];
 81             else sum[1][++sum[1][0]] = a[i]; 
 82         }
 83         for (int i = 2; i <= n; ++i) for (int j = 0; j < 2; ++j) sum[j][i] += sum[j][i - 1];  
 84         SEG::build(1, 1, n);
 85         for (int qq = 1, op, l, r; qq <= q; ++qq)
 86         {
 87             scanf("%d%d%d", &op, &l, &r);
 88             if (op == 1) printf("%lld\n", que(r) - que(l - 1));
 89             else if (op == 2) 
 90             {
 91                 int a = SEG::query(1, 1, n, l, r);
 92                 int b = (r - l + 1) - a;
 93                 SEG::update(1, 1, n, l, l + b - 1, 0);
 94                 SEG::update(1, 1, n, l + b, r, 1);
 95             }
 96             else
 97             {
 98                 int a = SEG::query(1, 1, n, l, r);
 99                 int b = (r - l + 1) - a;
100                 SEG::update(1, 1, n, l, l + a - 1, 1);
101                 SEG::update(1, 1, n, l + a, r, 0);
102             }
103         }
104     }
105     return 0;
106 }
View Code

 

 

J:Special Judge

Solved.

 $枚举每两条边, 判一下即可$

  1 #include<bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 const double eps = 1e-9;
  6 const int maxn = 1e4 + 10;
  7 
  8 int sgn(__int128 x)
  9 {
 10     if(x == 0) return 0;
 11     else return x > 0 ? 1 : -1;
 12 }
 13 
 14 struct Point{
 15     __int128 x, y;
 16     Point(){}
 17     Point(__int128 _x, __int128 _y)
 18     {
 19         x = _x;
 20         y = _y;
 21     }
 22 
 23     bool operator == (const Point &b) const
 24     {
 25         return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
 26     }
 27 
 28     bool operator < (const Point  &b) const
 29     {
 30         return sgn(x - b.x) == 0 ? sgn(y - b.y) : sgn(x - b.x);
 31     }
 32 
 33     Point operator - (const Point &b) const
 34     {
 35         return Point(x - b.x, y - b.y);
 36     }
 37 
 38     __int128 operator ^ (const Point &b) const
 39     {
 40         return x * b.y - y * b.x;
 41     }
 42 
 43     __int128 operator * (const Point &b) const
 44     {
 45         return x * b.x + y * b.y;
 46     }
 47 
 48 }P[maxn];
 49 
 50 struct Line{
 51     Point s, e;
 52     Line(){}
 53     Line(Point _s, Point _e)
 54     {
 55         s = _s;
 56         e = _e;
 57     }
 58 
 59     void adjust()
 60     {
 61         if(e < s) swap(s, e);
 62     }
 63 
 64     int segcrossseg(Line v)
 65     {
 66         int d1 = sgn((e - s) ^ (v.s - s));
 67         int d2 = sgn((e - s) ^ (v.e - s));
 68         int d3 = sgn((v.e - v.s) ^ (s - v.s));
 69         int d4 = sgn((v.e - v.s) ^ (e - v.s));
 70         if((d1 ^ d2) == -2 && (d3 ^ d4) == -2) return 2;
 71         return (d1 == 0 && sgn((v.s - s) * (v.s - e)) <= 0)
 72                 || (d2 == 0 && sgn((v.e - s) * (v.e - e)) <= 0)
 73                 || (d3 == 0 && sgn((s - v.s) * (s - v.e)) <= 0)
 74                 || (d4 == 0 && sgn((e - v.s) * (e - v.e)) <= 0);
 75     }
 76 
 77     bool pointtoseg(Point p)
 78     {
 79         return sgn((p - s) ^ (e - s)) == 0 && sgn((p - s) * (p - e)) <= 0;
 80     }
 81 }L[maxn];
 82 
 83 int n, m;
 84 int u[maxn], v[maxn];
 85 
 86 int main()
 87 {
 88     while(~scanf("%d %d", &n, &m))
 89     {
 90         for(int i = 1; i <= m; ++i) scanf("%d %d", u + i, v + i);
 91         for(int i = 1; i <= n; ++i)
 92         {
 93             int x, y;
 94             scanf("%d %d", &x ,&y);
 95             P[i] = Point(x, y);    
 96         }
 97         for(int i = 1; i <= m; ++i)
 98         {
 99                L[i] = Line(P[u[i]], P[v[i]]);
100             L[i].adjust();
101         }
102         int ans = 0;
103         for(int i = 1; i <= m; ++i) for(int j = i + 1; j <= m; ++j)
104         {
105             if(L[i].segcrossseg(L[j]) == 2) ans++; 
106             else if(L[i].segcrossseg(L[j]) == 1)
107             {
108                 if(u[i] == u[j])
109                 {
110                     if(!(L[i].pointtoseg(P[v[j]]) || (L[j].pointtoseg(P[v[i]])))) continue;
111                 }
112 
113                 if(u[i] == v[j])
114                 {
115                     if(!(L[i].pointtoseg(P[u[j]]) || (L[j].pointtoseg(P[v[i]])))) continue;
116                 }
117 
118                 if(v[i] == u[j])
119                 {
120                     if(!(L[i].pointtoseg(P[v[j]]) || (L[j].pointtoseg(P[u[i]])))) continue;
121                 }
122 
123                 if(v[i] == v[j])
124                 {
125                     if(!(L[i].pointtoseg(P[u[j]]) || (L[j].pointtoseg(P[u[i]])))) continue;
126                 }
127             
128                 ans++;
129             }
130         }
131         printf("%d\n", ans);
132     }
133     return 0;
134 }
View Code

 

posted @ 2019-01-24 22:35  Dup4  阅读(306)  评论(0编辑  收藏  举报