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 }
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 }
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 }
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 }
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 }
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 }