暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第二场)
这段时间自己都不知道该干些什么,比赛时候什么都想不到,全靠队友A题维持生计这样...补题进度也是一拖再拖,明后天又是两场连打,感觉又要堆一堆题了...看着补算了。
以下题解包括:
\[1005【HDU-6595】 \\ 1009【HDU-6599】 \\ 1010【HDU-6600】 \\ 1011【HDU-6601】 \\ 1012【HDU-6602】\]
【1005】 数学 HDU-6595 Everything Is Generated In Equal Probability
与我无瓜,比赛时候队友A的。据说是找规律
http://acm.hdu.edu.cn/showproblem.php?pid=6595
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <numeric>
#include <iostream>
#include <algorithm>
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 = 998244353;ll q_pow(ll a, ll b) {ll ans = 1;while(b) {if(b & 1) {ans = ans * a % mod;}a = a * a % mod;b >>= 1;}return ans;
}int main() {int n;while(~scanf("%d", &n)) {printf("%lld\n", (1ll*n*n-1)%mod*q_pow(9ll, mod-2)%mod);}return 0;
}
【1009】 回文自动机 HDU-6599 I Love Palindrome String
我不爱回文串,听他们说是回文自动机板子,然后我就去找板子了,然后一同乱改,然后A了。
http://acm.hdu.edu.cn/showproblem.php?pid=6599
回文自动机的大佬讲解和板子:https://blog.csdn.net/weixin_43093481/article/details/82889017
本题参考题解:https://www.cnblogs.com/xay5421/p/HDU6599.html
求有多少个 \([l,r]\) 满足 \(s[l,r]\) 和 \(s[l,(l+r)/2]\) 都是回文串。
考虑本质不同的回文串总共有 \(O(n)\) 种,然后统计每个满足条件的回文串出现次数和。
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <numeric>
#include <iostream>
#include <algorithm>
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 = 3e5+5;
const int N = 26;
const int seed = 131;char a[maxn];
ull hash1[maxn], hash2[maxn], pw[maxn];
int ans[maxn];ull get(int l, int r) {return hash1[r] - hash1[l-1]*pw[r-l+1];
}ull get2(int l, int r) {return hash2[l] - hash2[r+1]*pw[r-l+1];
}bool check(int l, int r){return get(l,r) == get2(l,r) && get(l,(l+r)>>1) == get2(l,(l+r)>>1);
}struct Palindromic_Tree {int nxt[maxn][N]; // next指针,next指针和字典树类似,指向的串为当前串两端加上同一个字符构成int fail[maxn]; // fail指针,失配后跳转到fail指针指向的节点ll cnt[maxn]; // 表示节点i表示的本质不同的串的个数(建树时求出的不是完全的,最后count()函数跑一遍以后才是正确的)int num[maxn]; // 表示以节点i表示的最长回文串的最右端点为回文串结尾的回文串个数int len[maxn]; // len[i]表示节点i表示的回文串的长度(一个节点表示一个回文串)int S[maxn]; // 存放添加的字符int last; // 指向新添加一个字母后所形成的最长回文串表示的节点。int n; // 表示添加的字符个数。int p; // 表示添加的节点个数。int ok[maxn]; // 判断是否可行int newnode(int l, int r) {// 新建节点for(int i = 0; i < N; ++i) nxt[p][i] = 0;cnt[p] = 0;num[p] = 0;len[p] = l;fail[p] = r;return p++;}void init() { // 初始化p = 0;newnode(0, 1);newnode(-1, 0);last = 0;n = 0;S[n] = -1; // 开头放一个字符集中没有的字符,减少特判fail[0] = 1;}int get_fail(int x, int y) { // 和KMP一样,失配后找一个尽量最长的while(a[y-len[x]-1] != a[y]) x = fail[x];return x;}void add(int c, int pos) {c -= 'a';int cur = get_fail(last, pos); // 通过上一个回文串找这个回文串的匹配位置if(!nxt[cur][c]) { // 如果这个回文串没有出现过,说明出现了一个新的本质不同的回文串int now = newnode(len[cur]+2, nxt[get_fail(fail[cur],pos)][c]); // 新建节点//fail[now] = nxt[get_fail(fail[cur], pos)][c]; // 和AC自动机一样建立fail指针,以便失配后跳转nxt[cur][c] = now;//num[now] = num[fail[now]] + 1;ok[nxt[cur][c]] = check(pos-len[nxt[cur][c]]+1, pos);}last = nxt[cur][c];cnt[last] ++;}void count() {for(int i = p-1; i >= 2; --i) {// 父亲累加儿子的cnt,因为如果fail[v]=u,则u一定是v的子回文串!cnt[fail[i]] += cnt[i];}for(int i = p-1; i >= 2; --i){ans[len[i]] += ok[i] * cnt[i];}}
}T;int main() {pw[0] = 1;for(int i = 1; i < maxn; i++) {pw[i] = pw[i-1]*seed;}while(~scanf("%s", a+1)) {T.init();int n = strlen(a+1);hash1[0] = 0;hash2[n+1] = 0;for(int i = 1; i <= n; i++) {hash1[i] = hash1[i-1]*seed + a[i]-'a'+1;}for(int i = n; i >= 1; i--) {hash2[i] = hash2[i+1]*seed + a[i]-'a'+1;}for(int i = 1; i <= n; i++) {T.add(a[i], i);ans[i] = 0;}T.count();for(int i = 1; i <= n; i++) {printf("%d%c", ans[i], i==n ? '\n':' ');}}return 0;
}
【1010】 水题 HDU-6600 Just Skip The Problem
就是找规律,发现答案就是 n!,然后 %(1e6+3),意味着大于 (1e6+3) 的答案都是 0。
http://acm.hdu.edu.cn/showproblem.php?pid=6600
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <numeric>
#include <iostream>
#include <algorithm>
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 = 1e6 + 3;const int maxn = 1e6+3;ll a[maxn+5];int main() {int n;a[0] = 1;for(int i = 1; i <= maxn; i++) {a[i] = a[i-1]*i % mod;}while(~scanf("%d", &n)) {if(n >= maxn) {printf("0\n");}else {printf("%lld\n", a[n]);}}return 0;
}
【1011】 斐波那契+主席树 HDU-6601 Keen On Everything But Triangle
比赛的时候肝了4个小时...从WA到TLE到WA到MLE再到WA,莫队被我疯狂魔改,每次都能被找出反例,于是我心态炸了。
http://acm.hdu.edu.cn/showproblem.php?pid=6601
给定 n 个数和 m 次询问,每次给定区间 \([l, r]\),要找到给定区间内最大的三角形。
因为斐波那契数的存在,我们可以知道:如果区间内一直不能构成三角形,那么最多也只会出现40多次这样的情况,因为 \(fi_{40+}\) 就已经会超过上界 \(1e^9\),因此我们对于每一个区间,只需要用主席树每次去处理区间前3大,依次往后找就可以了,这样的时间总时间复杂度就是:\(o(m*log(n)*40)\)。
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <numeric>
#include <iostream>
#include <algorithm>
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 = 1e5+5;int n, q, cnt;
int a[maxn], root[maxn];
vector<int> v;
struct node {int l, r, sum;
} T[maxn*40];int getid(int x) {return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
}void update(int l, int r, int &x, int y, int pos) {T[++cnt] = T[y];T[cnt].sum ++;x = cnt;if(l == r) {return ;}int mid = (l+r) / 2;if(mid >= pos) {update(l, mid, T[x].l, T[y].l, pos);}else {update(mid+1, r, T[x].r, T[y].r, pos);}
}int query(int l, int r, int x, int y, int k) {if(l == r) {return l;}int mid = (l+r) / 2;int sum = T[T[y].l].sum - T[T[x].l].sum;if(sum >= k) {return query(l, mid, T[x].l, T[y].l, k);}else {return query(mid+1, r, T[x].r, T[y].r, k-sum);}
}int main() {while(~scanf("%d%d", &n, &q)) {memset(root, 0, sizeof(root));memset(a, 0, sizeof(a));v.clear();cnt = 0;for(int i = 1; i <= n; i++) {scanf("%d", &a[i]);v.push_back(a[i]);}sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()), v.end());int new_n = (int)v.size();for(int i = 1; i <= n; i++) {update(1, new_n, root[i], root[i-1], getid(a[i]));}for(int i = 1 ; i <= q; i++) {int l, r; scanf("%d%d", &l, &r);int s = r - l + 1;if(s <= 2) {printf("-1\n");continue;}int a = v[query(1, new_n, root[l-1], root[r], s) - 1];int b = v[query(1, new_n, root[l-1], root[r], s-1) - 1];int c = v[query(1, new_n, root[l-1], root[r], s-2) - 1];if(a < b+c) {printf("%lld\n", 1ll*a+b+c);}else {int flag = 0;for(int i = 3; i <= s-1; i++) {a = b;b = c;c = v[query(1, new_n, root[l-1], root[r], s-i) - 1];if(a < b+c) {flag = 1;break;}}if(flag == 0) {printf("-1\n");}else {printf("%lld\n", 1ll*a+b+c);}}}}return 0;
}
【1012】 线段树+双端队列 HDU-6602 Longest Subarray
http://acm.hdu.edu.cn/showproblem.php?pid=6602
给你一个数组,数的范围是 \([1,C]\),给定 \(K\),让你找一个最长的区间使得区间内任意一个出现的数在该区间内的数量都大于 \(K\) 或者等于 0。
参考博客:https://blog.csdn.net/qq_40791842/article/details/97434430
整体思想就是枚举右端点,找最左的左端点。考虑建一颗线段树,每个叶子节点记录一改位置为左节点,当前枚举的节点为右节点的合法颜色种类数量,显然如果等于 C,那么以这个节点为左节点是合法的,由于线段树叶子节点最大权值为 C,所以可以通过维护一个最大值,和最大值对应的最左边的那个位置,查询这个位置就是最优左区间位置。
还需要用双端队列 \(deque\) 维护每个数的位置信息。
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <numeric>
#include <iostream>
#include <algorithm>
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 = 1e5+5;int n, c, k;
int a[maxn];
int sum[maxn<<2];
int pos[maxn<<2];
int lazy[maxn<<2];
deque<int> q[maxn]; // q[i]维护数 i 的最多 k 个最新位置信息void init() {for(int i = 0; i <= c; i++) {q[i].clear();q[i].push_back(0);}
}void push_up(int rt) {if(sum[rt<<1] >= sum[rt<<1|1]) {sum[rt] = sum[rt<<1];pos[rt] = pos[rt<<1];}else {sum[rt] = sum[rt<<1|1];pos[rt] = pos[rt<<1|1];}
}void push_down(int rt) {if(lazy[rt]) {sum[rt<<1] += lazy[rt];sum[rt<<1|1] += lazy[rt];lazy[rt<<1] += lazy[rt];lazy[rt<<1|1] += lazy[rt];lazy[rt] = 0;}
}void build(int l, int r, int rt) {sum[rt] = lazy[rt] = 0;pos[rt] = l;if(l == r) {return ;}int mid = (l+r) >> 1;build(l, mid, rt<<1);build(mid+1, r, rt<<1|1);
}void update(int L, int R, int l, int r, int rt, int x) {if(L <= l && r <= R) {sum[rt] += x;lazy[rt] += x;return ;}push_down(rt);int mid = (l+r) >> 1;if(L <= mid) {update(L, R, l, mid, rt<<1, x);}if(R > mid) {update(L, R, mid+1, r, rt<<1|1, x);}push_up(rt);
}pair<int, int> query(int L, int R, int l, int r, int rt) {if(L <= l && r <= R) {pair<int, int> temp;temp.first = sum[rt];temp.second = pos[rt];return temp;}push_down(rt);int mid = (l+r) >> 1;pair<int, int> ansl, ansr;if(L <= mid) {ansl = query(L, R, l, mid, rt<<1);}if(R > mid) {ansr = query(L, R, mid+1, r, rt<<1|1);}if(ansl.first >= ansr.first) {return ansl;}return ansr;
}int solve(int l, int r) {auto it = query(l, r, 1, n, 1);if(it.first != c) {return -1;}return it.second;
}int main() {while(~scanf("%d%d%d", &n, &c, &k)) {init();for(int i = 1; i <= n; i++) {scanf("%d", &a[i]);}if(k <= 1) {printf("%d\n", n);continue;}build(1, n, 1);int ans = 0;for(int i = 1; i <= n; i++) {int lst = q[a[i]].back();if(lst+1 <= i-1) {update(lst+1, i-1, 1, n, 1, -1);}if(q[a[i]].size() == k) {int fst = q[a[i]].front();q[a[i]].pop_front();int nxt = q[a[i]].front();update(fst+1, nxt, 1, n, 1, 1);}q[a[i]].push_back(i);update(i, i, 1, n, 1, c-1);int q = solve(1, i);if(q != -1) {ans = max(ans, i-q+1);}}printf("%d\n", ans);}return 0;
}
转载于:https://www.cnblogs.com/Decray/p/11271284.html
暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第二场)相关推荐
- 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第一场)
杭电多校第一场属实恐怖,我连补题的冲动都莫得了. 本来还想说按去年的经验来说,杭电是要比牛客稍微友好那么一丢丢的吧.结果当场打脸,签到题来了个最短路*2+网络流,这谁顶得住啊. 所以这两天都没在补这场 ...
- 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第四场)
本来想说这场放掉了,算了还是补了吧... 以下题解包括: \[1001[HDU-6614] \\ 1003[HDU-6616] \\ 1007[HDU-6620] \\ 1008[HDU-6621] ...
- 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第五场)
开启疯狂水题解模式,大概会持续好几次...直到我赶上进度为止. 以下题解包括: \[1001[HDU-6624] \\ 1004[HDU-6627] \\ 1005[HDU-6628] \\ 1006 ...
- 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第六场)
我胡汉三又滚回来了....保质期过了的题也得记下来. 以下题解包括: \[1002[HDU-6635] \\ 1005[HDU-6638] \\ 1006[HDU-6639] \\ 1008[HDU- ...
- 暑假N天乐【比赛篇】 —— 2019杭电暑期多校训练营(第三场)
以下题解包括: \[1002[HDU-6604] \\ 1004[HDU-6606] \\ 1006[HDU-6608] \\ 1007[HDU-6609] \\ 1009[HDU-6611]\] [ ...
- 2020杭电暑期多校02 10 - Lead of Wisdom (HDU6772) 常数坑
20200725005909 2020杭电暑期多校02 10 - Lead of Wisdom (HDU6772) 常数坑 如果一直 TLE,就看第三章. 一.题意 物品可能的种类有 kkk 种,编号 ...
- 2019牛客暑期多校训练营(第五场)C generator 2 (BSGS)
2019牛客暑期多校训练营(第五场)C generator 2 思路 x0=x0x_0 = x_0x0=x0 x1=a∗x0∗bx_1 = a * x_0 * bx1=a∗x0∗b x2=a∗ ...
- 2019牛客暑期多校训练营(第四场)----E- triples II
首先发出题目链接: 链接:https://ac.nowcoder.com/acm/contest/884/E 来源:牛客网 涉及:位运算,容斥定义,dp 点击这里回到2019牛客暑期多校训练营解题-目 ...
- 2019牛客暑期多校训练营(第三场)H.Magic Line
2019牛客暑期多校训练营(第三场)H.Magic Line 题目链接 题目描述 There are always some problems that seem simple but is diff ...
最新文章
- 文本类控件(EditView 的介绍)
- iOS核心动画高级技术(十三) 高效绘图
- 在VMware环境Windows server 2003下测试磁盘阵列实验
- js判断鼠标旋转度数以及顺逆方向详解
- Android系统语言默认设置为简体中文
- jemter安装Transactions per Second和Response Times Over Time插件
- 用数组存储循环序号的数据
- webstorm中vue项目--运行配制
- Zookeeper基本概念
- mysql sdi_MySQL 8.0新特性: 数据字典
- 利用 Python 进行数据分析(Python 数据分析)· 第 2 版
- php全局变量global和$GLOBALS
- progressbar使用方法:进度画面大小,进度画面背景,进度百分比
- java学习之Eclipse开发工具
- php后台登录,实现后台管理员登录功能
- 成都信息工程大学 809 软件工程导论简答题必背
- 英特尔第十代处理器为什么不支持win7_为什么i7处理器不支持win7系统,背后的真实原因?...
- 失败程序员的十年总结
- 怎样使用计算机定时关机,win10怎么定时关机?
- 腾讯实习生面试经历及入职体验