• 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
    ", 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
    ", 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("
    ");
    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, " 
    "[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
    ", 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
    ", 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
    ", 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
    ", ans);
    132     }
    133     return 0;
    134 }
    View Code
  • 相关阅读:
    Redis命令行之Hash
    Redis命令行之String
    Redis配置
    访问者模式【行为模式】
    状态模式【行为模式】
    责任链模式【行为模式】
    观察者模式【行为模式】
    策略模式【行为模式】
    模板方法模式【行为模式】
    组合模式【结构模式】
  • 原文地址:https://www.cnblogs.com/Dup4/p/10317369.html
Copyright © 2020-2023  润新知