2019.10.22 校内CSP%你赛

我太难了

先说好没有代码T1

题目大意:

给定一些形如|ax+b|的式子,求最小的x使得它们的和最小。

算法一:

大家知道零点分段法 对于这n个式子我们有n+1个取值范围 使得展开这n个式子得到的新式子不同

而对于每一个形成的式子,因为我们有这个x的取值范围,所以我们可以在O(1)的复杂度求出它的最小值。

而我们从最左边的取值范围开始,对于相邻的两个取值范围我们可以用O(1)的复杂度转移,即我们可以用O(n)遍历所有可能形成的n个式子,每个算一下答案即可。

需要注意的是,对于所有a[i]=0,我们需要去除这些点,将对应的b[i]加成一个常量,随后加在ans上。

还需要注意的是,当a<0时,我们通过把a和b分别取绝对值得到a>0的等价的式子,这样便于处理。

算法二:

我们容易知道,|ax+b|是一个下凸函数,而这些|ax+b|的和因为是一个新的|ax+b|,所以依然是一个下凸函数。

所以我们考虑三分或者爬山法,得到x的取值即可。

T2

题目大意:

给定一个有向图y,求构造一个有向图使得每条边起点编号比终点小,且1号点到n号点恰好有y条路径。子任务满足n越小越分多。

我们先构造一个64个节点的完全图,这样从1-63号节点到64号节点的贡献依次是2^63,2^62,2^61……2^0.

也就是说我们先连1-64,此时1-64有一种方案,再往图里加入63号点,补全完全图,此时加了一种方案,再加62号点,加了2种方案……以此类推。

我们再新建一个0号节点作为起点,将y快速幂分解,从向分解出的2^k1,2^k2……的k1,k2……对应的完全图中的节点连边即可。

T3

题目大意:

给定一段序列,旋转其中一段连续子序列后可以得到一个新的序列,设新的序列中有x个数满足a[i]=i(a[i]是序列中是的数),求不同旋转方案下最大的x。

我们旋转一段子序列时有一个旋转中心,对于每个旋转中心可以对应的旋转子段,设其为[l,r],则对于有效的旋转子段,必有a[l]==r&&a[r]==l,否则它没有[l+1,r-1]更优;

所以我们把所有有效的旋转子段按照旋转中心为关键字排序,同时再给每个旋转中心开一个vector存储其所有有效的子段,其中这些子段按照从短到长排序;

对于一个子段,将其分为三部分:

(1)[1,l);

(2)[l,r];

(3)(r,n]。

(1)(3)两部分因为旋转前后不变,所以我们分别利用前缀、后缀数组存储其答案贡献,查询复杂度为O(1);

(2)部分中,因为每个子段距离上一个更新的子段只多出了一个新的答案贡献(a[l]==r&&a[r]==l),所以该子段(2)部分的答案为2*k,其中k是其在该旋转中心的vector内的位置。

所以只需要扫描所有的[l,r]即可在O(1)的复杂度内检查出其答案。总复杂度O(n)。

T4

题目大意:

给定一段序列,设好的子序列是一段连续子序列满足其中所有数互质,求该序列中好的子序列的个数。

我们知道互质的本质是不存在相同的质因子,所以我们先用欧拉筛筛出所有质数;

而我们从头扫描所有[l,r],用book数组记录该序列中出现过的质因子,每次加入一个新的数就判断它是否含有这些质因子,若有,则该序列不好。分解一个数的质因子需要的复杂度是O(logn)。

总复杂度O(nlogn)。

我。果然。越来越能口hu了。

原文地址:https://www.cnblogs.com/qxds/p/11728205.html

时间: 2024-11-02 20:44:59

2019.10.22 校内CSP%你赛的相关文章

2019.10.22模拟赛

T1 合并集合 有\(n\)个集合,第\(i\)个集合记为\(S_i\),集合按环状排列,即第\(i + 1\)个集合右边是第\(i\)个集合,第\(n\)个集合右边是第\(i\)个集合. 一开始每个集合里只有一个数,每次你可以选择两个相邻的集合\(S,T\),然后合并成\(S \cup T\),之后你可以获得收益\(|S| \times |T|\),其中\(|S|\)表示集合\(S\)的元素个数. 你需要一直进行以上的操作直到只剩一个集合为止,求能获得的最大的收益之和. 断环为链,复制两倍区间

【10.22校内测试】【二分】【二分图】【很像莫队的乱搞/树状数组】

Solution 谁能想到这道题卡读入??还卡了70pts??? 二分+$n^2$check就行了 Code #include<bits/stdc++.h> using namespace std; int n, m; int sum[2005][2005]; void read(int &x) { x = 0; char ch = getchar(); while(ch > '9' || ch < '0') ch = getchar(); while(ch >= '

2019.10.22 csp-s模拟测试82 反思总结

算了 我在干什么orz T2: #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=1e5+10,p=1500007,mod=998244353; int n,len,cnt1=1,cnt2=1,lens; char s[2*N],c[2*N]; int tree1[2*N][27],tree2[2*N][27]; unsigned long lon

【2019.10.25 OI-Killer的模拟赛】3.鸡数

题目链接 题意: 定义“鸡数”指从高位到低位单调不减的数.求$[a,b]$之间有多少个“鸡数”.$t$组询问. $1\le t\le 10^5,\; 1\le a\le b\le 2^{31}-1$ 分析: 数位DP.设$f[i][j]$表示长度为$i$,最高位是$j$的“鸡数”个数,那么$$f[i][j]=\sum\limits^9_{k=j}f[i-1][k]$$ 且$$f[1][i]=1\;(1\le i\le 9)$$ 那么对于一个长度为$l$的$n$且由低到高位写成$s_{1\dots

2019.10.22 用TCP实现服务端并发接收

client import socket client = socket.socket() client.connect( ('127.0.0.1',8888) ) while 1: msg = input('input>>>') if msg == 'q': break client.send(msg.encode('utf-8')) data = client.recv(1024).decode('utf-8') print(data) client.close() server线程

2019.10.22日上午学习内容

1.学习了a标签的使用方法及主要功能(超链接,下载,锚点). (1)超链接<a href="http://www.baidu.com">跳转到百度</a> (2)下载,网页能识别打开的,不能下载,如txt文件 ,图片文件,网页文件等:网页识别不了的可以下载,如压缩包等 <a href="..wenjian.rar">点击下载</a>一定要找好路径 (3)锚链接,主要是本网页内,回顶部回底部的练习 <div id=

10.22 模拟赛

10.22 模拟赛 T1 染色 考虑每个连通块删成一棵树就好了. mmp场上就我路径压缩写炸.... #include<iostream> #define MAXN 200006 using namespace std; int n , m; int fa[MAXN] , siz[MAXN] , book[MAXN] , sz[MAXN]; int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } int main() {

离线赛 2019.10.31

2019.10.30 \[ Ameiyo \] A: 地精部落 : Dp , 前缀和优化 Dp B: 深入虎穴 : 图,结论题 C: 教义问答手册 : 分治,分块,Dp A 挺简单的一道 Dp ...看 这个博客 . B 其实可以用 dijsktra 做这道题,但是每次用来更新的都是自己的次小值. 因为当你走到当前点时,老虎会让你不能走最小值,所以是用次小值更新. 每次也是拿次小值最小的点出来更新. ll mi[N][2]; struct NODE { int id; ll w; inline

8.25重庆南开CSP信心赛

8.25重庆南开CSP信心赛 A.填数字 时间限制:1s空间限制:128MB 题面描述信竞队的同学们在一个N*N的方格矩阵上填数字.开始时,所有矩阵里的数字都是0. 同学们一共给 个子矩阵填了数字,每次填的数都是从 这区间中选一个数字,然后给对应矩阵全部填上该数字.比如:第1步,选了一个子矩阵,将数字2填上:2 2 2 02 2 2 02 2 2 00 0 0 0第2步,选了一个子矩阵,将数字7填上:2 2 2 02 7 7 72 7 7 70 0 0 0第3步,选了一个子矩阵,将数字3填上:2