文章目录

  • HDU6950 Mod, Or and Everything
  • HDU6954 Minimum spanning tree
  • HDU6958 KD-Graph
  • HDU6957 Maximal submatrix
  • HDU6955 Xor sum

中超联赛

CSL中超可没巨佬们训练强度大

“什么是BSGS、莫队、KD tree”

我看我是完全不懂噢

HDU6950 Mod, Or and Everything

题意

求(nmod1)∣(nmod2)∣...∣(nmod(n−1))(n\ mod\ 1)|(n\ mod \ 2)|...|(n\ mod\ (n-1))(n mod 1)∣(n mod 2)∣...∣(n mod (n−1))的值

分析

打比赛时,

队友:经过化简可以得到答案为2k−12^k-12k−1

我:观察样例可以得到答案为2k−12^k-12k−1

QAQ

而实际上std的思路:nmodi≤⌈n2⌉−1n\ mod\ i \leq \lceil \frac{n}{2}\rceil-1n mod i≤⌈2n​⌉−1,所以nmod(n−i)=in\ mod\ (n-i)=in mod (n−i)=i

所以这个和值就是000到⌈n2⌉−1\lceil \frac{n}{2}\rceil-1⌈2n​⌉−1的所有整数的和. 求出来是2k−12^k-12k−1,这里的kkk是某个带nnn的式子,懒得认真推的话可以根据样例猜出,是令n=2xn=2^xn=2x,这个xxx向下取整再减1得到kkk. 但如果xxx本来就是整数,那么xxx还要再减去1.(总之看代码吧,或者去看std代码)

代码

#include <bits/stdc++.h>
#define fors(i, a, b) for(int i = (a); i <= (b); ++i)
#define lson k<<1
#define rson k<<1|1
#define pb push_back
#define lowbit(x) ((x)&(-(x)))
#define mem(a) memset(a, 0, sizeof(a))
#define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0)
#define int long long
const int inf = 0x3f3f3f3f;
const double dinf = 1e100;
typedef long long ll;
//const ll linf = 9223372036854775807LL;
// const ll linf = 1e18;
using namespace std;signed main()
{DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;while(t--){int n;cin >> n;int x = 0, res = n;while(res){res >>= 1LL;x++;}if(n == 1LL){cout << 0 << endl;continue; }if(n == (1LL << (x - 1LL))) x--;cout << (1LL << (x - 1LL)) - 1LL << endl;}return 0;
}

HDU6954 Minimum spanning tree

题意

有一个n−1n-1n−1个节点的带权完全图,节点标记为2,3,...,n2,3,...,n2,3,...,n. 完全图中从点iii到点jjj的边的权值大小为lcm(i,j)lcm(i,j)lcm(i,j),请你求出这个图的最小生成树。n≤10000000n\leq 10000000n≤10000000.

分析

容易知道,对任何一个边(i,j)(i,j)(i,j),这个边的权值不会小于max(i,j)max(i,j)max(i,j).

那么对于一个合数,它连向自己的因子即可,这时候边的权值就是这个合数。由于因子一定比自己小,所以在2,3,..i2,3,..i2,3,..i中一定存在。

而对于一个质数xxx,和任意一点iii相连,都有lcm(x,i)=x⋅ilcm(x,i)=x·ilcm(x,i)=x⋅i. 故令iii最小,取2即可保证边权最小。

分析完毕。找出质数,然后分类处理即可。线性筛处理之

其他

首先看到题:哇,1e81e81e8的范围,这怎么做。这算法都给限制到O(n)O(n)O(n)了,难不成是有什么公式?

思考一会之后:(其实已经得到正解)用线性筛试一波,自己调试1.5秒,完蛋

尝试各种卡常之后:优化到1.1秒了,实在顶不住了,要不直接交?

交上去之后:卧槽,MLE,那我不求MSTMSTMST前缀和了吧,直接算,但是这样更容易超时了,纠结

再交:居然700多ms过了,杭电评测机强啊

打完比赛后,才发现,原来数据规模看错了,是1e71e71e7,根本不需要卡()

代码

#include <bits/stdc++.h>
#define fors(i, a, b) for(int i = (a); i <= (b); ++i)
#define lson k<<1
#define rson k<<1|1
#define pb push_back
#define lowbit(x) ((x)&(-(x)))
#define mem(a) memset(a, 0, sizeof(a))
#define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0)
#define int long long
const int inf = 0x3f3f3f3f;
const double dinf = 1e100;
typedef long long ll;
//const ll linf = 9223372036854775807LL;
// const ll linf = 1e18;
using namespace std;
const int maxn = 1e7 + 10; // 比赛的时候看成1e8,导致多了一次MLE
bool p[maxn];
int pr[maxn];
int pre[maxn];
void Prime(){int cnt = 0;mem(p);p[0] = p[1] = 1;for(int i = 2; i < maxn; ++i){if(!p[i]) pr[cnt++] = i;for(int j = 0; j < cnt && pr[j] * i < maxn; ++j){p[pr[j] * i] = 1;if(i % pr[j] == 0) break;}}pre[0] = pre[1] = pre[2] = 0;for(int i = 3; i < maxn; ++i){if(!p[i]) pre[i] = pre[i - 1] + 2 * i;else pre[i] = pre[i - 1] + i;}
}
signed main()
{DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;Prime();while(t--){int n;cin >> n;cout << pre[n] << endl;}return 0;
}

HDU6958 KD-Graph

看到过题数不多以及题面比较奇怪就没做了,以后一定不能盲目看榜,以及耐心读懂题

题意

有一个nnn点mmm边的图(n≤100000n\leq100000n≤100000, m≤500000m\leq500000m≤500000),你需要将其分割成恰好KKK组,满足:

  1. 每组中任取两个点p,qp,qp,q,他们之间的路径中,最长边不大于DDD
  2. 不同组中任取两个点p,qp,qp,q,他们之间的路径中,所有边都大于DDD

现在给定图和KKK,问你是否找得到一个满足条件的DDD,如果找得到,输出最小的DDD. 否则输出−1-1−1.

分析

容易知道,相同权值的边要么不在任何组内部,要么全都在同一组点里面。假如相同权值的边,有的在组内,有的在组外的话,这个DDD值肯定只会更大不会更小。

那么贪心思路显而易见了,将所有边按权值升序排序,使用并查集,从左往右,将所有权值相同的边的点合并。然后统计并查集数量,更新答案。也就是在保证“相同权值的边要么不在任何组内部,要么全都在同一组点里面”这个性质的前提下寻找能否分为KKK组。而要使DDD尽可能小,应让处于组内的边尽可能小,所以使用升序。

代码

#include <bits/stdc++.h>
#define fors(i, a, b) for(int i = (a); i <= (b); ++i)
#define lson k<<1
#define rson k<<1|1
#define pb push_back
#define pii pair<int, int>
#define lowbit(x) ((x)&(-(x)))
#define mem(a) memset(a, 0, sizeof(a))
#define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0)
// #define int long long
const int inf = 0x3f3f3f3f;
const double dinf = 1e100;
typedef long long ll;
//const ll linf = 9223372036854775807LL;
// const ll linf = 1e18;
using namespace std;
const int maxn= 100000 + 5;
int fa[maxn];
struct edge{int l, r, val;bool operator < (const edge& b)const{return val < b.val;}
};
vector<edge> e;
inline int find(int x)
{if(fa[x] == x) return x;return fa[x] = find(fa[x]);
}
bool join(int x, int y)
{int ans = 0;int fx = find(x), fy = find(y);if(fx == fy) return 0;fa[fy] = fx;return 1;
}
signed main()
{DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;while(t--){e.clear();int n, m, k;cin >> n >> m >> k;fors(i, 1, n) fa[i] = i;int u, v, c;fors(i, 1, m){cin >> u >> v >> c;e.pb({u, v, c});}sort(e.begin(), e.end());int now = n; // 并查集数量,初始为nbool flag = 0;int ans = 0;for(int i = 0; i < m; ++i){if(i == 0 || e[i].val != e[i - 1].val){if(now == k) break;}if(!join(e[i].l, e[i].r)) continue;now--;ans = e[i].val;}cout << (now == k ? ans : -1) << endl;}return 0;
}

HDU6957 Maximal submatrix

题意

给出一个矩阵,要你找一个最大的子矩阵,要求这个子矩阵每一列从上往下都是单调不下降序列。输出最大子矩阵的面积

分析

悬线法,将每个不比上面的元素小的元素标记,然后用这些标记过的元素组成子矩阵。接下来使用悬线dp即可。需要注意的是,子矩阵的最上面一行是可以不被标记的。

代码

(比赛时自己凹的二维dp一直超时,应该是复杂度超过O(n2)O(n^2)O(n2)了)

第一次接触到悬线法,代码可能相对繁琐

#include <bits/stdc++.h>
#define fors(i, a, b) for(int i = (a); i <= (b); ++i)
#define lson k<<1
#define rson k<<1|1
#define pb push_back
#define lowbit(x) ((x)&(-(x)))
#define mem(a) memset(a, 0, sizeof(a))
#define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0)
// #define int long long
const int inf = 0x3f3f3f3f;
const double dinf = 1e100;
typedef long long ll;
//const ll linf = 9223372036854775807LL;
// const ll linf = 1e18;
using namespace std;
const int maxn = 2005;
bool v[maxn][maxn];
int l[maxn][maxn];
int r[maxn][maxn];
int u[maxn][maxn];
signed main()
{DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;while(t--){mem(v), mem(l), mem(r), mem(u);int n, m;cin >> n >> m;fors(i, 1, n){fors(j, 1, m){cin >> u[i][j];l[i][j] = j;r[i][j] = j;}}fors(i, 1, n){fors(j, 1, m){if(i == 1 || u[i][j] >= u[i - 1][j]){v[i][j] = 1;}}}fors(i, 1, n){fors(j, 2, m){if(v[i][j] && v[i][j - 1]) l[i][j] = l[i][j - 1];}for(int j = m - 1; j >= 1; --j){if(v[i][j] && v[i][j + 1]) r[i][j] = r[i][j + 1];}}mem(u);fors(i, 1, n){fors(j, 1, m) u[i][j] = 1;}int ans = 0;fors(i, 1, n){fors(j, 1, m){if(v[i][j] && v[i - 1][j]){l[i][j] = max(l[i - 1][j], l[i][j]);}if(v[i][j]) u[i][j] = u[i - 1][j] + 1;}for(int j = m; j >= 1; --j){if(v[i][j] && v[i - 1][j]){r[i][j] = min(r[i - 1][j], r[i][j]);}}}fors(i, 1, n){fors(j, 1, m){ans = max(ans, u[i][j] * (r[i][j] - l[i][j] + 1));}}cout << ans << endl;}return 0;
}

HDU6955 Xor sum

题意

给一个整数数组,你需要找到最短的区间,其按位异或和不小于kkk. 如果有多个,找出左端点最左的

分析

先转化一下。异或运算里,任意xxx的逆元是xxx本身,故对于前缀和pre[i]pre[i]pre[i],pre[j]pre[j]pre[j],iii到jjj的异或和可以表示为pre[i]pre[i]pre[i]^pre[j]pre[j]pre[j].

这之后,直接存异或和,问题转化为:找到两个相距最近的i,ji,ji,j,其异或和不小于kkk.

枚举右端点,然后可能的左端点用TrieTrieTrie树维护,从左到右找,每次找到一个可能的编号就覆盖一下,这样能保证最后找到的是最右边的。不过也可以直接保存最右边的节点。

以后千万不要看着std调试代码,调着调着就调得跟std一模一样了

不过说白了也是之前从来没用过trie吧orz,根本不熟

代码

/*** @file    :vsDebug.cpp* @brief   :* @date    :2021-07-21* @Motto   :Love Sakurai Yamauchi Forever*/
#include <bits/stdc++.h>
#define fors(i, a, b) for(int i = (a); i <= (b); ++i)
#define lson k<<1
#define rson k<<1|1
#define pb push_back
#define lowbit(x) ((x)&(-(x)))
#define mem(a) memset(a, 0, sizeof(a))
#define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0)
// #define int long long
const int inf = 0x3f3f3f3f;
const double dinf = 1e100;
typedef long long ll;
//const ll linf = 9223372036854775807LL;
// const ll linf = 1e18;
using namespace std;
const int maxn = 1e5 + 10;
const int mnx = (1LL << 24) + 10;
int p[mnx][2], res[mnx], a[maxn];
signed main()
{DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;while(t--){int n, k;cin >> n >> k;fors(i, 1, n){cin >> a[i];a[i] ^= a[i - 1]; // 只存前缀和}int l = -1, r = n, ans = 1;res[1] = -1;p[1][0] = p[1][1] = 0; // initfors(i, 0, n){int x = 1;int tmp = -1;for(int j = 29; j >= 0; --j){if(!x) break;int u = (a[i] >> j) & 1; // 从上往下第j位if(!((k >> j) & 1)){if(p[x][u ^ 1]){tmp = max(tmp, res[p[x][u ^ 1]]);}x = p[x][u];}else x = p[x][u ^ 1];}if(x) tmp = max(tmp, res[x]);if(tmp >= 0 && i - tmp < r - l) l = tmp, r = i;x = 1;for(int j = 29; j >= 0; --j){int u = (a[i] >> j) & 1;if(!p[x][u]){ans++;p[x][u] = ans, res[ans] = -1;p[ans][0] = p[ans][1] = 0;}x = p[x][u];res[x] = max(res[x], i);}}if(l >= 0) cout << l + 1 << ' ' << r << endl;else cout << -1 << endl;}return 0;
}

2021“MINIEYE杯”中国大学生算法设计超级联赛(1)个人解题报告相关推荐

  1. 【2021杭电多校赛】2021“MINIEYE杯”中国大学生算法设计超级联赛(3)签到题3题

    2021"MINIEYE杯"中国大学生算法设计超级联赛(3) Start Time : 2021-07-27 12:00:00 End Time : 2021-07-27 17:0 ...

  2. 【2021杭电多校赛】2021“MINIEYE杯”中国大学生算法设计超级联赛(1)签到题15869

    2021"MINIEYE杯"中国大学生算法设计超级联赛(1) Start Time : 2021-07-20 12:10:00 End Time : 2021-07-20 17:1 ...

  3. 2021“MINIEYE杯”中国大学生算法设计超级联赛

    2021"MINIEYE杯"中国大学生算法设计超级联赛 1006 Given a sequence of integers of length n, find the shorte ...

  4. 2021“MINIEYE杯”中国大学生算法设计超级联赛(2)

    2021"MINIEYE杯"中国大学生算法设计超级联赛(2) 1008 I love exam (类背包DP) 1010 I love permutation (数学构造,剩余系) ...

  5. 7068 Dota2 Pro Circuit 杭电多校(2021“MINIEYE杯”中国大学生算法设计超级联赛9) [贪心+双指针]

    题目 Dota2 Pro Circuit *Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Oth ...

  6. 【2021杭电多校赛】2021“MINIEYE杯”中国大学生算法设计超级联赛(5)签到题4题

    Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 Miserable Faith 33.33%(19/57) 1002 String Mod 2 ...

  7. 【2021杭电多校赛】2021“MINIEYE杯”中国大学生算法设计超级联赛(8)

    1006 GCD Game (博弈论,nim游戏,质因子个数) 题意:有n个数a1,a2....an两个人玩游戏,Alice先动,Bob后动每次可以将一个数变为他的因子,直到不能动就输了. 题解:将问 ...

  8. 2021“MINIEYE杯”中国大学生算法设计超级联赛(8)(1002,1004,1006,1009)

    前言 依旧是白嫖账号,只打了一些题/kk 正题 1002 Buying Snacks 题目大意 nnn个物品,每个可以买一次也可以不买,如果买需要选择1/21/21/2块钱的,然后也可以相邻两个一起买 ...

  9. 2021“MINIEYE杯”中国大学生算法设计超级联赛(7)部分题解

    前言 找大佬嫖到个号来划水打比赛了,有的题没写或者不是我写的就不放了. 目前只有:1004,1005,1007,1008,1011 正题 题目链接:https://acm.hdu.edu.cn/con ...

最新文章

  1. python -socket -client
  2. redis持久化方案
  3. Elmah 日志记录组件
  4. 乐观锁、悲观锁简单分析,回忆旧(新)知识...
  5. Linux系统挂载操作mount详解
  6. nginx主模块指令
  7. linux grub rescue 光盘,Ubuntu9.10用安装光盘如何进入linux rescue方式?
  8. sqlserver 插入数据时异常,仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'XXXXX.dbo.XXXXXXXXX'中的标识列指定显式值。...
  9. jenkins 忘记用户名和密码
  10. RFID芯片有什么用
  11. EFCore 调试远程SqlServer数据库提示信号灯超时时间已到
  12. 局域网SDN技术硬核内幕 一 分布式任意播网关
  13. Typecho网站访问浏览总量统计插件PageViews升级版
  14. SPSS——连续变量的描述统计
  15. python 负数索引
  16. “衣带渐宽终不悔,为伊消得人憔悴”的赏析
  17. PHP动态网站开发期末试卷,《PHP动态网站开发实例教程》课程考核方案
  18. 计算机cpu执行时间 指令条数的单位,计算机原理2015年10月真题(02384)
  19. Node版本管理工具
  20. 2021年山东省职业院校技能大赛中职组网络安全赛项竞赛样题

热门文章

  1. Qcustomplot设置使用时间刻度坐标轴
  2. MVS学习(一):综述论文阅读记录
  3. 移动端用户登录注册案例
  4. 快速排序-单边循环代码解析
  5. 由涌金系掌门人魏东因患抑郁症及强迫症而自杀身亡说起
  6. 台电android n彩蛋,十核动力强劲!还有彩蛋 台电T20开箱
  7. ATSHA204A-MAHDA-T国产替代加密芯片
  8. python实战爬虫有道翻译与解决{“errorCode”:50}反爬虫问题
  9. 1104 -- 打折
  10. 从星巴克看:NFT不仅仅是一种数字资产,更代表着一种全新的交互模式