B. Wrong Answer

构造一个长度为 2000 的数组,满足最大“子段和 $\times$ 子段长度”比最大子段和刚好大 k

sol:

一个比较好的构造方法:

令数组总和为 $S$,然后构造 $a_1,a_2,...,a_{1998}=0,a_{1999}=-d,a_{2000}=S+d$

这样正确答案是 $2000 \times S$,最大子段和是 $S+d$

发现 $S = \frac{k+d}{1999}$

于是令 $d=1999-(k \space mod \space 1999)$ 即可

#include<bits/stdc++.h>
#define LL long long
#define rep(i,s,t) for(register int i = (s),i##end = (t); i <= i##end; ++i)
#define dwn(i,s,t) for(register int i = (s),i##end = (t); i >= i##end; --i)
using namespace std;
inline int read()
{int x=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f=-f;for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';return x*f;
}
int main()
{int k = read();int d = 1999 - k % 1999;int S = (k + d) / 1999;cout << 2000 << endl;rep(i, 1, 1998) cout << 0 << " ";cout << -d << " ";cout << S + d << endl;
}

View Code

D. isolation

给一个数组 a,把数组分成若干不相交的子段,使得每段“只出现一次的数”不超过 k 个

求有多少种分法,膜 998244353

$n \leq 10^5$

sol:

考虑 dp,令 $f(l,r)=[l,r]中只出现一次的数的数量$,假设可以很快的算出 $f(l,r)$ ,令 $dp(i)=前i个的分法$ ,则 $dp(0)=1,dp(n) = \sum\limits_{i=0}^{n} dp(i) \times [f(i+1,n) \leq k]$

现在只要快速算出 $f(l,r)$ 并想办法加速转移即可

然后是一系列神仙操作:

首先,枚举 $r$,尝试构造一个数组 $b[l,r]$ 使得对于枚举的 $r$,$f(l,r) = \sum\limits_{i=l}^r b[i]$,

因为我们要枚举 $r$ ,所以只需考虑如何快速使 $b_x[]$ 变成 $b_{x+1}[]$ 即可($b_x$ 表示当 $r=x$ 时的 $b[]$)

一开始,$b_0[0]=0$,为方便描述,记 $pre(x)$ 为数字 $x$ 上一次在 $a$ 数组中出现的位置,保证存在

对于给定的 $a_{x+1}$

如果 $a_{x+1}$ 在之前至少出现过 $2$ 次,把 $b[pre(pre(x+1))]$ 设为 $0$

如果 $a_{x+1}$ 在之前出现过 $1$ 次,把 $b[pre(x+1)]$ 设为 $-1$

最后不管如何,把 $b[x+1]$ 设为 $1$

这样就能保证:出现两次或以上的数对 sumb 的贡献为 0,出现一次的数对 sumb 的贡献为 1

b 数组可以 $O(n)$ 递推出来,考虑怎么优化转移

考虑分块(这就是我的知识盲区了)

每块 [l,r] 维护:

1. $f(l,r)$ (也就是 sumb)

2. 对于每一个 $i \in [-\sqrt{n},\sqrt{n}]$,维护对于每个 $f(x,r) \leq i$ 的 $x$ ,维护 $dp(x-1)$ 的和

对于 2. ,因为 $i$ 是递增的,我们可以对 $i$ 维护一个前缀和

转移的时候在本块以及前面的块里查,本块查的是 $[0,k]$ ,往前查就把右端点每次减这一块的 sumb 就可以了

这样递推到每一个 $r$ 的时候,单块修改 $O(\sqrt{n})$ ,状态转移最多涉及到 $O(\sqrt{n})$ 个块

一路递推到 $n$ 就可以了

#include<bits/stdc++.h>
#define LL long long
#define rep(i, s, t) for(register int i = s, i##end = t; i <= i##end; ++i)
#define dwn(i, s, t) for(register int i = s, i##end = t; i >= i##end; --i)
using namespace std;
inline int read()
{int x = 0, f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar())if(ch == '-')f = -f;for(;isdigit(ch);ch=getchar())x = 10 * x + ch - '0';return x * f;
}
const int mod = 998244353,maxn = 1e5 + 10;
int n,k;
int a[maxn], b[maxn], nx[maxn], cur[maxn], f[maxn], bl[maxn];
inline void inc(int &x, int y) {x += y; if(x >= mod) x -= mod;}
struct block
{int l, r, sum, sumf[700], sz;void calsum(){memset(sumf, 0, sizeof(sumf));int cur = 0;dwn(i, r, l){cur += b[i];inc(sumf[sz + cur], f[i - 1]);}rep(i, 1, sz + sz) inc(sumf[i], sumf[i - 1]);}int query(int pos){if(pos + sz < 0)return 0;return sumf[min(pos + sz, sz + sz)];}
}bs[350];inline void update(int pos, int val)
{f[pos] = val;bs[bl[pos + 1]].calsum();
}int query(int x)
{int ans = bs[bl[x]].query(k), cursum = bs[bl[x]].sum;dwn(i, bl[x]-1, 1){inc(ans, bs[i].query(k - cursum));cursum += bs[i].sum;}return ans;
}int main()
{n = read(), k = read();rep(i, 1, n) a[i] = read();rep(i, 1, n) nx[i] = cur[a[i]], cur[a[i]] = i;f[0] = 1; int kk = sqrt(n);rep(i, 1, n) bl[i] = (i - 1) / kk + 1;rep(i, 1, bl[n]){bs[i].r = min(i * kk, n);bs[i].l = bs[i-1].r + 1;bs[i].sz = bs[i].r - bs[i].l + 1;}bs[1].calsum();rep(i, 1, n){if(nx[nx[i]]){int pos = nx[nx[i]]; b[pos]++;bs[bl[pos]].sum++; bs[bl[pos]].calsum();}if(nx[i]){int pos = nx[i]; b[pos] -= 2;bs[bl[pos]].sum -= 2; bs[bl[pos]].calsum();}b[i]++; bs[bl[i]].sum++; bs[bl[i]].calsum();update(i, (f[i] = query(i)));}cout << f[n] << endl;
}

View Code

E.Legendary Tree

交互题,有一棵不知道形态的树

每次可以给定两个不相交点集 $A,B$ 和一个点 $v$ ,系统会回答你满足 $v$ 在 $s->t$ 简单路径上,$s\in A,t\in B$,这样的点对 $(s,t)$ 数量

求树形态

$n \leq 500,交互次数 \leq 11111$

sol:

一道我不是很喜欢的构造题

因为构造出来基本上只有题解的一种

那我就发题解吧

首先,令 $1$ 为根,对每个 $i$ ,询问 $({1},{2,3,...,n},i)$,这样可以问出来每个点的子树大小,这样是 $(n-1)$ 次($1$ 号点的子树大小显然是 $n$)

之后把点按子树大小从小到大排序,按字数大小递增顺序枚举每个点,设 $v_i$ 为子树第 $i$ 大的点,

设已知点(下面已经知道,上面还不知道)的集合为 $X$,一开始,$X$ 中只有 $v_1$,因为显然 $v_1$ 是一个叶子

每次我们按如下步骤:

1.询问 $({1},{X},v_i)$,得到 $v_i$ 的直接儿子数量,记为 $k$

2.把 $X$ 中元素按任意顺序排成一列 $X_1,X_2,...,X_{|X|}$

3.重复 $k$ 次,每次二分找一个最小的 $m$,满足:询问 $({1},{X_1,X_2,...,X_m},v_i)$ 的结果大于 $0$,这个等价于 $X_m$ 和 $v_i$ 有一条边相连,每次找到这个 $m$ 就把 $X_m$ 删了(因为不满足 $X$ 的定义)

4.把 $v_i$ 加入 $X$

总询问次数 $(n-1) + (n-1) + (n-1) log_2n$

会感觉“好强啊但给我自己做我永远都做不出来”

可能这就是菜吧 quq

#include<bits/stdc++.h>
#define LL long long
#define rep(i,s,t) for(register int i = (s),i##end = (t); i <= i##end; ++i)
#define dwn(i,s,t) for(register int i = (s),i##end = (t); i >= i##end; --i)
using namespace std;
inline int read() {int x=0,f=1;char ch;for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f=-f;for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';return x*f;
}
int query(vector<int> s, vector<int> t, int node) {cout << s.size() << endl;for(int i = 0; i < (int)s.size(); ++i) {if(i != 0)putchar(' ');cout << s[i] + 1;}cout << endl;cout << t.size() << endl;for(int i = 0; i < (int)t.size(); ++i) {if(i != 0)putchar(' ');cout << t[i] + 1;}cout << endl;cout << node + 1 << endl;return read();
}
vector<int> nd, size, p;
vector<pair<int, int>> ans;
set<int> X;
int main() {int n;cin >> n;for (int i = 1; i < n; ++i) nd.push_back(i);p.resize(n);for (int i = 0; i < n; ++i) p[i] = i;size.resize(n);size[0] = n;for (int i = 1; i < n; ++i) size[i] = query({ 0 }, nd, i);sort(p.begin(), p.end(), [](int x, int y) { return size[x] < size[y]; });for (auto node : p) {if (size[node] != 1) {while (!X.empty()) {vector<int> cur(X.begin(), X.end());if (!query({ 0 }, cur, node)) break;int l = 0, r = (int)cur.size();while (l + 1 < r) {int mid = l + r >> 1;if (query({ 0 }, vector<int>(cur.begin() + l, cur.begin() + mid), node)) r = mid;else l = mid;}ans.emplace_back(node, cur[l]);X.erase(cur[l]);}}X.insert(node);}cout << "ANSWER" << endl;for (auto p : ans) cout << p.first + 1 << " " << p.second + 1 << endl;return 0;
}

View Code

转载于:https://www.cnblogs.com/Kong-Ruo/p/10432159.html

CF Round 542 Div1.相关推荐

  1. [Codeforces Round #254 div1] C.DZY Loves Colors 【线段树】

    题目链接:CF Round #254 div1 C 题目分析 这道题目是要实现区间赋值的操作,同时还要根据区间中原先的值修改区间上的属性权值. 如果直接使用普通的线段树区间赋值的方法,当一个节点表示的 ...

  2. Codeforces Round 542 (Div. 2)

    layout: post title: Codeforces Round 542 (Div. 2) author: "luowentaoaa" catalog: true tags ...

  3. 【codeforces】【比赛题解】#915 Educational CF Round 36

    虽然最近打了很多场CF,也涨了很多分,但是好久没写CF的题解了. 前几次刚刚紫名的CF,太伤感情了,一下子就掉下来了,不懂你们Div.1. 珂学的那场我只做了第一题--悲伤. 这次的Education ...

  4. 【codeforces】【比赛题解】#849 CF Round #431 (Div.2)

    cf的比赛越来越有难度了--至少我做起来是这样. 先看看题目吧:点我. 这次比赛是北京时间21:35开始的,算是比较良心. [A]奇数与结束 "奇数从哪里开始,又在哪里结束?梦想从何处起航, ...

  5. cf Round 613

    A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积. 保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这 ...

  6. 【codeforces】【比赛题解】#937 CF Round #467 (Div. 2)

    没有参加,但是之后几天打了哦,第三场AK的CF比赛. CF大扫荡计划正在稳步进行. [A]Olympiad 题意: 给\(n\)个人颁奖,要满足: 至少有一个人拿奖. 如果得分为\(x\)的有奖,那么 ...

  7. 【codeforces】【比赛题解】#960 CF Round #474 (Div. 1 + Div. 2, combined)

    终于打了一场CF,不知道为什么我会去打00:05的CF比赛-- 不管怎么样,这次打的很好!拿到了Div. 2选手中的第一名,成功上紫! 以后还要再接再厉! [A]Check the string 题意 ...

  8. cf Round#779 D 388535

    前言: 这个方法挺慢的,不如其他大佬们的方法(但是我看不懂他们写的),所以自己来搞个.最坏的情况是n^2的复杂度,但是基本到不了最坏的情况.而且可以D1,D2两题通用! 核心思想: 假设 l^x=a1 ...

  9. 【codeforces】【比赛题解】#851 CF Round #432 (Div.2)

    cf真的难-- 点我浏览丧题. [A]Arpa和她对墨西哥人浪的研究 Arpa正在对墨西哥人浪进行研究. 有n个人站成一排,从1到n编号,他们从时刻0开始墨西哥人浪. 在时刻1,第一个人站起来. 在时 ...

最新文章

  1. 盘启动盘_[装机]推荐唯二的两个开源免费的启动盘工具,轻松创建USB启动盘
  2. 重新想象 Windows 8 Store Apps (49) - 输入: 获取输入设备信息, 虚拟键盘, Tab 导航, Pointer, Tap, Drag, Drop...
  3. android线程间通信的几种方法_Android 技能图谱学习路线
  4. java代码防止sql注入_动态Java代码注入
  5. openlayers基础系列教程(一)
  6. 一首歌,一种情感,一种心情
  7. SQL 使用总结四(关于索引)
  8. centos7 部署elasticsearch
  9. 帮你深度探寻Spring循环依赖源码实现!面经解析
  10. C++设计模式——模板方法(Template Method)
  11. 易语言64位进程注入DLL
  12. 基于ThinkPHP6+Layui的后台管理框架
  13. VMware虚拟机下载及Ubuntu安装指南
  14. 深度学习入门——神经元
  15. 微信公众号模板消息源码
  16. 开源之夏 2022 来袭,欢迎报名 RadonDB 社区项目
  17. pvid与access的关系_交换机应用之端口模式(access、trunk和hybird)、是否标记(tag、untag)、端口缺省vlan(pvid、native id)...
  18. 服务器市场混乱,信息安全是关键
  19. 并不简单的翻页时钟(一):样式篇(Flex布局、line-height、data-set用法、css before after伪元素)
  20. linux下分区比例,安全地调整Linux分区大小的三种方法 | MOS86

热门文章

  1. 《视觉锤》 读书笔记
  2. Google Capture The Flag 2019 (Quals) WP
  3. 字节码编程,Byte-buddy篇二《监控方法执行耗时动态获取出入参类型和值》
  4. scrapy配置user-agent中间件和ip代理中间件
  5. 深度学习理论篇之----前世、今生、未来
  6. 服务器装系统提示获取分区失败,u盘装系统时获取硬盘分区失败怎么办
  7. 此文记录了我从研二下学期到研三上学期的找工历程,包括百度、腾讯、网易、移动、电信、华为、中兴、IBM八家企业的面试总结和心得--转...
  8. 22.【终结篇】poco/airtest+pytest+allure+jenkins框架篇
  9. 项目经理面对项目陷困境该这样采取措施
  10. 【实习】一面数据面试面经