Hello2020(前四题题解)
Hello2020(前四题题解)
Hello,2020!新的一年从快乐的掉分开始……
我在m3.codeforces.com这个镜像网站中一开始还打不开D题,我……
还有话说今天这场为什么那么多二分。
比赛传送门:https://codeforces.com/contest/1284。
A. New Year and Naming
题目大意:这题就是一个干支纪年法。每年的名字分两段,第一段在n个字符串中取,第二段在m个字符串中取,每过一年就各取下一个,如果取到n(m)就去取第一个。
纯模拟,加上一点点字符串操作。
又丑又长的代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define rep(x, l, r) for(int x = l; x <= r; x++)
#define repd(x, r, l) for(int x = r; x >= l; x--)
#define clr(x, y) memset(x, y, sizeof(x))
#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair
#define MAXN 2005
#define fi first
#define se second
#define SZ(x) ((int)x.size())
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
const int INF = << ;
const int p = ;
int lowbit(int x){ return x & (-x);}
int fast_power(int a, int b){ int x; for(x = ; b; b >>= ){ if(b & ) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;} char st1[MAXN][], st2[MAXN][]; int main(){
int n, m;
scanf("%d%d", &n, &m);
rep(i, , n) scanf("%s", st1[i]);
rep(i, , m) scanf("%s", st2[i]);
int q;
scanf("%d", &q);
rep(i, , q){
int x;
scanf("%d", &x);
int len = strlen(st1[(x - ) % n + ]);
rep(j, , len - ) putchar(st1[(x - ) % n + ][j]);
puts(st2[(x - ) % m + ]);
}
return ;
}
-A
B.New Year and Ascent Sequence
题目大意:给你n个序列,每次取任意两个序列(可以取同一个,并且交换前后顺序算不同种)接起来(比如说‘11’和‘22’就是‘1122’)。问这n2个接成序列中共有多少个序列中存在顺序对。
不难看出,如果一个序列中本身存在顺序对,接成的序列也肯定存在顺序对。
判断方法
if(x > minx) flag = 1;
将它们找出来后直接统计入答案,套上一个小学学的容斥原理
ans = 1ll * 2 * cnt1 * n - 1ll * cnt1 * cnt1;
然后主要问题就是这些剩下的没有顺序对的序列。
很显然凡是最大值比这个序列最小值大的,就可以和这个序列接起来。
将最大值排序后二分一下最小的最大值就好。
代码如下
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define rep(x, l, r) for(int x = l; x <= r; x++)
#define repd(x, r, l) for(int x = r; x >= l; x--)
#define clr(x, y) memset(x, y, sizeof(x))
#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair
#define MAXN 100005
#define fi first
#define se second
#define SZ(x) ((int)x.size())
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
const int INF = << ;
const int p = ;
int lowbit(int x){ return x & (-x);}
int fast_power(int a, int b){ int x; for(x = ; b; b >>= ){ if(b & ) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;} vi a, b; int main(){
int n;
scanf("%d", &n);
int cnt1 = , cnt2 = ;
rep(i, , n){
int k;
scanf("%d", &k);
int minx = INF, maxx = -INF;
bool flag = ;
rep(j, , k){
int x;
scanf("%d", &x);
if(x > minx) flag = ;
minx = min(minx, x);
maxx = max(maxx, x);
}
if(flag) cnt1++;
else{
cnt2++;
a.pb(minx);
b.pb(maxx);
}
}
sort(all(b));
ll ans = 1ll * * cnt1 * n - 1ll * cnt1 * cnt1;
rep(i, , SZ(b) - ){
ans += cnt2 - (upper_bound(all(b), a[i]) - b.begin());
}
printf("%I64d\n", ans);
return ;
}
-B
C.New Year and Permutation
题目大意:在所有由[1,n]组成的排列中,有多少对数(l,r)满足max{pl,pl+1,…,pr} - min{pl,pl+1,…,pr} = r - l。
似乎解释的不是很清楚,再来个样例解释一下。
当n = 3时,所有的排列为[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]。
对于[1,2,3]:(1,1)中max = 1, min = 1, r - l = 0,成立;(1,3)中max = 3, min = 1, r - l = 2,成立。
对于[1,3,2]:(1,2)中max = 3, min = 1, r - l = 1,不成立。
别的懒得说了,原题样例说明有。
这道题一开始看的时候有点慌,浪费了好多时间。
后来一想,不就分别统计长度为i的子段满足条件。
我们可以很轻松的求出不同子段出现次数,所有该长度的子段出现次数为:
排列个数×每个排列中出现的次数 = n!×(n - i +1)
然后该长度不同子段的个数为n!/ (n - i)!,稍微证明一下或者列举几个便可以得出。
然后求所有符合条件的字段个数,(1,2,…,i ) 到(n - i + 1,n - i + 2,…, n )一共有n - i + 1种,然后每种的排列有i!个。
所有长度为i的字段对答案的贡献 = 不同子段的出现个数 × 符合的长度为i子段的个数
= n!× (n - i + 1) / ( n!/ ( n - i )!) × ( n - i + 1 ) × i!
= ( n - i )! × ( n - i + 1) × ( n - i +1 ) × i!
这个式子看上去挺好看的,然后求个总和就好。
代码特别短:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define rep(x, l, r) for(int x = l; x <= r; x++)
#define repd(x, r, l) for(int x = r; x >= l; x--)
#define clr(x, y) memset(x, y, sizeof(x))
#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair
#define MAXN 250005
#define fi first
#define se second
#define SZ(x) ((int)x.size())
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
const int INF = << ;
int p;
int lowbit(int x){ return x & (-x);}
int fast_power(int a, int b){ int x; for(x = ; b; b >>= ){ if(b & ) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;} int pow[MAXN]; int main(){
int n;
scanf("%d%d", &n, &p);
pow[] = ;
rep(i, , n){
pow[i] = 1ll * pow[i - ] * i % p;
}
int ans = ;
rep(i, , n){
int s = 1ll * pow[n - i] * (n - i + ) % p * (n - i + ) % p * pow[i] % p;
ans = (ans + s) % p;
}
printf("%d\n", ans);
return ;
}
-C
D.New Year and Conference
题目大意:有n个人,每个人在a会场讲话开始时间为sai,结束时间为eai,在b会场开始时间为sbi,结束时间为ebi。是否存在一个集合中的人在a市场没有时间重叠在b市场有重叠或在b市场没有重叠在a市场有有重叠。设两个人开始结束时间分别为(u,v)和(x,y),当max(x,u) <= min(y,v)时两人重叠。存在重叠时输出“NO”,否则输出“YES”(似乎有什么不对的地方)。
提前申明一下,这道题我自己代码一直过不了,但是群里有人按照我的解法过了……代码也差不多……
只WA了第10个点(加了个特判过了),现在对拍跑了2个半小时还没跑出一组错误数据……
我的解法甚是奇怪……
首先判断a会场不重叠b会场重叠的情况,发现我们对于每个人a会场只要判断左边不重叠的情况,右边的到时候会枚举到的。
对于i这个人,要是eaj < sai,那么这两个人就不会重叠。
所以我们以sai为关键字进行排序,二分查找可以找出所有与i不重叠的人。
但是对每个人找他左边的人的区间肯定要超时,因为左边的人一定是从1开始的一个区间,我们记录下对于每个人i所有的以i为最右边的不重叠的人pi,j。(即不存在一个人k使得eai < eak < sapi,j)
然后只需要判断b会场是否有重叠,也就是说对第i个人,所有他左边的不重叠人j的[sbj,ebj]这个区间是否和[sbi,ebi]有重合,变成了一个区间覆盖问题。
用线段树进行维护,将区间[sbi,ebi]更改为已覆盖,判断pi中是否有点的讲话区间中有已覆盖的点。
对于另一种情况b会场不重叠a会场重叠情况和这个相同。
放上我的WA掉的代码(仅供参考,对着打出锅了别怪我):
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define rep(x, l, r) for(int x = l; x <= r; x++)
#define repd(x, r, l) for(int x = r; x >= l; x--)
#define clr(x, y) memset(x, y, sizeof(x))
#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair
#define MAXN 500005
#define MAXM 2000005
#define fi first
#define se second
#define SZ(x) ((int)x.size())
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
const int INF = << ;
const int p = ;
int lowbit(int x){ return x & (-x);}
int fast_power(int a, int b){ int x; for(x = ; b; b >>= ){ if(b & ) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;} struct node1{
int l1, r1, l2, r2;
}a[MAXN];
struct node2{
int l, r;
bool flag, tag;
}tree[MAXM];
bool ans;
int num[MAXM];
vi ve1[MAXN], ve2[MAXN]; void pushup(int q){
tree[q].flag = tree[q << ].flag || tree[q << | ].flag;
} void pushdown(int q){
if(!tree[q].tag) return;
tree[q << ].flag = tree[q << ].tag = ;
tree[q << | ].flag = tree[q << | ].tag = ;
tree[q].tag = ;
} void build(int q, int l, int r){
tree[q].l = l;
tree[q].r = r;
tree[q].tag = ;
tree[q].flag = ;
if(l == r) return;
int mid = (l + r) >> ;
build(q << , l, mid);
build(q << | , mid + , r);
pushup(q);
} void update(int q, int l, int r){
if(tree[q].l > r || tree[q].r < l) return;
if(tree[q].l >= l && tree[q].r <= r){
tree[q].flag = ;
tree[q].tag = ;
return;
}
pushdown(q);
update(q << , l, r);
update(q << | , l, r);
pushup(q);
} void query(int q, int l, int r){
if(tree[q].l > r || tree[q].r < l) return;
if(tree[q].l >= l && tree[q].r <= r){
ans = ans || tree[q].flag;
return;
}
pushdown(q);
query(q << , l, r);
query(q << | , l, r);
pushup(q);
} bool cmp1(node1 a, node1 b){
return a.r1 < b.r1;
} bool cmp2(node1 a, node1 b){
return a.r2 < b.r2;
} int main(){
int n, m = ;
scanf("%d", &n);
rep(i, , n){
scanf("%d%d%d%d", &a[i].l1, &a[i].r1, &a[i].l2, &a[i].r2);
num[++m] = a[i].l1;
num[++m] = a[i].r1;
num[++m] = a[i].l2;
num[++m] = a[i].r2;
}
sort(num + , num + m + );
rep(i, , n){
a[i].l1 = lower_bound(num + , num + m + , a[i].l1) - num;
a[i].r1 = lower_bound(num + , num + m + , a[i].r1) - num;
a[i].l2 = lower_bound(num + , num + m + , a[i].l2) - num;
a[i].r2 = lower_bound(num + , num + m + , a[i].r2) - num;
}
sort(a + , a + n + , cmp1);
rep(i, , n){
int l = , r = n, ans = ;
while(l <= r){
int mid = (l + r) >> ;
if(a[mid].r1 < a[i].l1){
ans = mid;
l = mid + ;
}
else r = mid - ;
}
ve1[ans].pb(i);
}
build(, , m);
rep(i, , n){
update(, a[i].l2, a[i].r2);
rep(j, , SZ(ve1[i]) - ){
int x = ve1[i][j];
ans = ;
query(, a[x].l2, a[x].r2);
if(ans){
puts("NO");
return ;
}
}
}
sort(a + , a + n + , cmp2);
rep(i, , n){
int l = , r = n, ans = ;
while(l <= r){
int mid = (l + r) >> ;
if(a[mid].r2 < a[i].l2){
ans = mid;
l = mid + ;
}
r = mid - ;
}
ve2[ans].pb(i);
}
build(, , m);
rep(i, , n){
update(, a[i].l1, a[i].r1);
rep(j, , SZ(ve2[i]) - ){
int x = ve2[i][j];
ans = ;
query(, a[x].l1, a[x].r1);
if(ans){
puts("NO");
return ;
}
}
}
puts("YES");
return ;
}
-D
Hello2020(前四题题解)的更多相关文章
- Codeforces Round #612 (Div. 2) 前四题题解
这场比赛的出题人挺有意思,全部magic成了青色. 还有题目中的图片特别有趣. 晚上没打,开virtual contest打的,就会前三道,我太菜了. 最后看着题解补了第四道. 比赛传送门 A. An ...
- ACM ICPC 2018 青岛赛区 部分金牌题题解(K,L,I,G)
目录: K Airdrop I Soldier Game L Sub-cycle Graph G Repair the Artwork ———————————————————— ps:楼主脑残有点严 ...
- 10.9 guz模拟题题解
感谢@guz 顾z的题题解 考试共三道题,其中 第一题help共10个测试点,时间限制为 1000ms,空间限制为 256MB. 第二题escape共20个测试点,时间限制为1000ms2000ms, ...
- 【ZROI 537】贪心题 题解
[ZROI 537]贪心题 题解 Link Solution 最大的一边直接放到一起贪心即可 着重讲小的一边 已知对于二分图匹配,其答案即为最大流 令时间集合为 \(T = {1,2,3,\dots, ...
- Codeforces Round #524 (Div. 2)(前三题题解)
这场比赛手速场+数学场,像我这样读题都读不大懂的蒟蒻表示呵呵呵. 第四题搞了半天,大概想出来了,但来不及(中途家里网炸了)查错,于是我交了两次丢了100分.幸亏这次没有掉rating. 比赛传送门:h ...
- Educational Codeforces Round 53 (Rated for Div. 2) (前五题题解)
这场比赛没有打,后来补了一下,第五题数位dp好不容易才搞出来(我太菜啊). 比赛传送门:http://codeforces.com/contest/1073 A. Diverse Substring ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) (前三题题解)
这场比赛好毒瘤哇,看第四题好像是中国人出的,怕不是dllxl出的. 第四道什么鬼,互动题不说,花了四十五分钟看懂题目,都想砸电脑了.然后发现不会,互动题从来没做过. 不过这次新号上蓝名了(我才不告诉你 ...
- Codeforces Round #519 by Botan Investments(前五题题解)
开个新号打打codeforces(以前那号玩废了),结果就遇到了这么难一套.touristD题用了map,被卡掉了(其实是对cf的评测机过分自信),G题没过, 700多行代码,码力惊人.关键是这次to ...
- Good Bye 2019(前五题题解)
这套也是后来补得. 我太菜了,第三题就卡着了.想了好久才做出来,要是参加了绝对掉分. D题是人生中做完的第一道交互题,不容易. 比赛传送门 A.Card Game 题目大意:一共有n张互不相同的牌,玩 ...
随机推荐
- 11 session 使用
#session 使用app.secret_key = "dsada12212132dsad1232113"app.config['PERMANENT_SESSION_LIFETI ...
- 2018-10-15-Winforms-可能遇到的-1000-个问题
title author date CreateTime categories Winforms 可能遇到的 1000 个问题 lindexi 2018-10-15 09:35:15 +0800 20 ...
- Android Studio(六):Android Studio添加注释模板
Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...
- WPF Converter(转)
WPF Binding 用于数据有效性校验的关卡是它的 ValidationRules 属性,用于数据类型转换的关卡是它的 Converter 属性.下面是实例: 1. Binding 的数据校验 & ...
- Python--day19--collections模块
常用模块一的各个模块解释: 文件名不要起跟模块名一样:(模块本身就是一个py文件) collection模块: namedtuple方法: 例1: 例2: dequeue方法:双端队列 有序字典Ord ...
- <STL源码剖析> 6.3.6 power
计算power的算法说明 http://www.sxt.cn/u/324/blog/2112 翻译自 http://videlalvaro.github.io/2014/03/the-power-a ...
- Python--day65--模板语言之filter
参考的原文链接:http://www.cnblogs.com/liwenzhou/p/7931828.html Filters(过滤器) 在Django的模板语言中,通过使用 过滤器 来改变变量的显示 ...
- javascript异步编程 Async/await
Async/await Async/await 在学习他之前应当补充一定的 promise 知识 它是一种与 promise 相配合的特殊语法,目前被认为是异步编程的终级解决方案 值得我们每一个人学习 ...
- 深度解读 - TDD详细(测试驱动开发)
本文结构: 什么是 TDD 为什么要 TDD 怎么 TDD FAQ 学习路径 延伸阅读 什么是 TDD TDD 有广义和狭义之分,常说的是狭义的 TDD,也就是 UTDD(Unit Test Driv ...
- 使用Squid做代理服务器,Squid单网卡透明代理配置详解(转)
使用Squid做代理服务器 说到代理服务器,我们最先想到的可能是一些专门的代理服务器网站,某些情况下,通过它们能加快访问互联网的速度.其实,在需要访问外部的局域网中,我们自己就能设置代理,把访问次数较 ...