CCPC-Wannafly Winter Camp Day5 (Div2, onsite)

Replay:


Dup4:

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

 X:

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

A:Cactus Draw

扫描二维码关注公众号,回复: 5056365 查看本文章

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

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

猜你喜欢

转载自www.cnblogs.com/Dup4/p/10317369.html
今日推荐