博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第六场)
阅读量:5300 次
发布时间:2019-06-14

本文共 8057 字,大约阅读时间需要 26 分钟。

我胡汉三又滚回来了....保质期过了的题也得记下来。

以下题解包括:

\[1002【HDU-6635】 \\ 1005【HDU-6638】 \\ 1006【HDU-6639】 \\ 1008【HDU-6641】 \\ 1012【HDU-6645】\]

【1002】 LIS+暴力 HDU-6635 Nonsense Time

参考:

给定长度为 \(n\) 的两个数组 \(a,b\)\(b_i\) 表示 \(a\) 中下标为 \(b_i\) 的数字当前可用,求 \(b_i\) 对应的 \(a\) 中的 LIS,\(a\) 中是 \([1,n]\) 的全排列。

由于数据随机生成,LIS 的期望长度为 \(\sqrt{n}\),删除元素在 LIS 中的概率为 \(\frac{1}{\sqrt{n}}\),因此总复杂度:\(o(n\sqrt{n}log(n)))\)。先求解全部的 LIS,然后从后往前遍历数组 \(b\),如果删除的元素在 LIS 中就重新求一次。需要记录 LIS 的路径。

#include #include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;typedef unsigned long long ull;const double PI = acos(-1.0);const double eps = 1e-6;const int inf = 0x3f3f3f3f;const int mod = 1e9 + 7;const int maxn = 5e4+5;int n;int a[maxn];int b[maxn];int vis[maxn];int ans[maxn];int temp[maxn];int path[maxn];int used[maxn];int solve() { int len = 0; for(int i = 1; i <= n; i++) { if(vis[a[i]] == 1) { continue; } int x = lower_bound(temp, temp+len, a[i]) - temp; if(x == len) { temp[len++] = a[i]; path[i] = len; } else { temp[x] = a[i]; path[i] = x + 1; } } memset(used, 0, sizeof(used)); int x = len; for(int i = n; i >= 1; i--) { if(vis[a[i]] == 1) { continue; } if(path[i] == x) { used[a[i]] = 1; x--; } } return len;}int main() { int t; scanf("%d", &t); while(t--) { memset(vis, 0, sizeof(vis)); scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for(int i = 1; i <= n; i++) { scanf("%d", &b[i]); } ans[n] = solve(); for(int i = n-1; i >= 1; i--) { vis[a[b[i+1]]] = 1; if(used[a[b[i+1]]] == 0) { ans[i] = ans[i+1]; } else { ans[i] = solve(); } } for(int i = 1; i <= n; i++) { printf("%d%c", ans[i], i==n?'\n':' '); } } return 0;}

【1005】 线段树 HDU-6638 Snowy Smile

参考:

给定 \(n(\leq 2000)\) 个点坐标和对应的权值,求最大权值和矩阵。

每次枚举上下边界,每次向线段树中加点,维护上下边界内的最大子段和【区间最大子段和】,要注意移动上边界时可能会有多个点在当前直线上,同样的,移动下边界时要把边界上的所有点都更新后才能更新 \(ans\)

#include #include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;typedef unsigned long long ull;const double PI = acos(-1.0);const double eps = 1e-6;const int inf = 0x3f3f3f3f;const int mod = 1e9 + 7;const int maxn = 2e3+5;struct node{ int x, y; ll val; bool operator < (const node &q) const { if(y == q.y) { return x < q.x; } return y > q.y; }}p[maxn];struct NODE { ll sum, lsum, rsum, maxsum;}T[maxn << 2];int n; vector
vx, vy;int get_xid(int x) { return lower_bound(vx.begin(), vx.end(), x) - vx.begin() + 1;}int get_yid(int y) { return lower_bound(vy.begin(), vy.end(), y) - vy.begin() + 1;}void pushup(int rt) { T[rt].sum = T[rt<<1].sum + T[rt<<1|1].sum; T[rt].lsum = max(T[rt<<1].lsum, T[rt<<1].sum + T[rt<<1|1].lsum); T[rt].rsum = max(T[rt<<1|1].rsum, T[rt<<1|1].sum + T[rt<<1].rsum); T[rt].maxsum = max(T[rt<<1].rsum+T[rt<<1|1].lsum, max(T[rt<<1].maxsum, T[rt<<1|1].maxsum));}void build(int l, int r, int rt) { T[rt].sum = T[rt].lsum = T[rt].rsum = T[rt].maxsum = 0; if(l == r) { return ; } int mid = (l+r) >> 1; build(l, mid, rt<<1); build(mid+1, r, rt<<1|1); pushup(rt);}void update(int l, int r, int pos, int val, int rt) { if(l == r) { T[rt].sum = T[rt].lsum = T[rt].rsum = T[rt].maxsum = T[rt].sum+val; return ; } int mid = (l+r) >> 1; if(pos <= mid) { update(l, mid, pos, val, rt<<1); } else { update(mid+1, r, pos, val, rt<<1|1); } pushup(rt);}int main() { int t; scanf("%d", &t); while(t--) { vx.clear(); vy.clear(); scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d%d%lld", &p[i].x, &p[i].y, &p[i].val); vx.push_back(p[i].x); vy.push_back(p[i].y); } sort(vx.begin(), vx.end()); vx.erase(unique(vx.begin(), vx.end()), vx.end()); sort(vy.begin(), vy.end()); vy.erase(unique(vy.begin(), vy.end()), vy.end()); int new_n = vx.size(); for(int i = 1; i <= n; i++) { p[i].x = get_xid(p[i].x); p[i].y = get_yid(p[i].y); } sort(p+1, p+1+n); ll ans = 0; int lst_y = -1; for(int i = 1; i <= n; i++) { if(lst_y == p[i].y) { continue; } build(1, new_n, 1); for(int j = i; j <= n; ) { int k; for(k = j; k <= n && p[k].y == p[j].y; k++) { update(1, new_n, p[k].x, p[k].val, 1); } ans = max(ans, T[1].maxsum); j = k; } lst_y = p[i].y; } printf("%lld\n", ans); } return 0;}

【1006】 思维 HDU-6639 Faraway

\(n\) 个二维坐标点(士兵),他们有一个共同的目的地 \((x_{e},y_{e})\),知道 \(x_e\)\(y_e\) 都在 \([0,m]\) 的范围内,但是他们都只知道自己位置 \((x_i,y_i)\) 和目标的大概情况为 \((|x_{i}-x_{e}|+|y_{i}-y_{e}|) \% k_{i} = t_{i}\) 现在问你有多少个可能的目标 \((x_e,y_e)\)

\(|x_i - x_e| + |y_i - y_e|\) 的绝对值拆掉,则每个点 \((x_i, y_i)\) 会将平面分割成 4 个部分,一共 \(n^2\) 个区域。枚举每个区域,计算该区域中可能的终点数量。因为 \(lcm(2, 3, 4, 5) = 60\),所以只需要枚举 \(x_e\)\(y_e\) 模 60 的余数,\(o(n)\) 判断是否可行。

#include #include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;typedef unsigned long long ull;const double PI = acos(-1.0);const double eps = 1e-6;const int inf = 0x3f3f3f3f;const int mod = 1e9 + 7;int n, m;vector
vx, vy;struct node { int x, y; int k, t;}p[15];int check(int a, int b) { for(int i = 1; i <= n; i++) { if((abs(a-p[i].x)+abs(b-p[i].y))%p[i].k != p[i].t) { return 0; } } return 1;}int cal(int x, int y) { if(y-x-1 < 0) { return 0; } return ((y-x-1)/60) + 1; }int main() { int t; scanf("%d", &t); while(t--) { vx.clear(); vy.clear(); scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d%d%d%d", &p[i].x, &p[i].y, &p[i].k, &p[i].t); vx.push_back(p[i].x); vy.push_back(p[i].y); } vx.push_back(0); vx.push_back(m+1); vy.push_back(0); vy.push_back(m+1); sort(vx.begin(), vx.end()); vx.erase(unique(vx.begin(), vx.end()), vx.end()); int nx = vx.size(); sort(vy.begin(), vy.end()); vy.erase(unique(vy.begin(), vy.end()), vy.end()); int ny = vy.size(); ll ans = 0; for(int i = 0; i < nx-1; i++) { for(int j = 0; j < ny-1; j++) { for(int k = 0; k < 60; k++) { for(int l = 0; l < 60; l++) { if(check(vx[i]+k, vy[j]+l)) { ans += 1ll*cal(vx[i]+k, vx[i+1])*cal(vy[j]+l, vy[j+1]); } } } } } printf("%lld\n", ans); } return 0;}

【1008】 数学 HDU-6641 TDL

队友写的,就酱。

#include
#include
#include
#include
#include
#include
#define lson node<<1#define rson node<<1|1using namespace std;typedef long long ll;const ll inf = 2e18;const ll mod = 998244353;const int maxn = 1e5 + 20;ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b);}int main() { int t; scanf("%d", &t); while (t--) { ll k, m; scanf("%lld%lld", &k, &m); ll ans = inf; int flag = 0; for (int i = 1; i <= 2000; i++) { ll n = k ^ i; int cnt = 0; int j = 1; for (; j <= 1000; j++) { if (gcd(j + n, n) == 1) { cnt++; if (cnt == m) break; } } if ((n + j) == (i + n)) { ans = min(ans, n); flag = 1; } } if (flag) printf("%lld\n", ans); else printf("-1\n"); }}

【1012】 水题 HDU-6645 permutation 2

我也不知道比赛时候为什么会去写拓扑...

就排个序一人一个分了就行。

#include #include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;typedef unsigned long long ull;const double PI = acos(-1.0);const double eps = 1e-6;const int inf = 0x3f3f3f3f;const int mod = 1e9 + 7;int a[100005];int main() { int t; scanf("%d", &t); while(t--) { int n; scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } sort(a, a+n); ll ans1 = 0, ans2 = 0; for(int i = n-1; i >= 0; i-=2) { ans1 = ans1 + 1ll*a[i]; } for(int i = n-2; i >= 0; i-=2) { ans2 = ans2 + 1ll*a[i]; } printf("%lld %lld\n", ans1, ans2); } return 0;}

转载于:https://www.cnblogs.com/Decray/p/11365864.html

你可能感兴趣的文章
沟通技巧系列 - 入门篇
查看>>
个人附加作业
查看>>
手游包压缩技术和云更新技术主要能实现什么功能?
查看>>
sed命令
查看>>
转换日期格式的工具类
查看>>
第三方控件获取值问题的解决(附转载的easyUI datagrid 时间格式化(两种))
查看>>
SET IDENTITY_INSERT 和 DBCC CHECKIDENT
查看>>
hearthbuddy中的Class276
查看>>
kentico version history and upgrade
查看>>
关于HostnameVerifier接口的解读
查看>>
Swift的闭包
查看>>
关于session_cache_expire 的理解
查看>>
lock和synchronized如何选择?
查看>>
decltype
查看>>
抽象类
查看>>
C++面向对象基础知识
查看>>
PY----Python
查看>>
[转载]识别真假搜索引擎(搜索蜘蛛)方法
查看>>
如何查看linux服务器内存使用情况
查看>>
Charles 3断点篡改数据
查看>>