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=,f=;char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f=-f;
for(;isdigit(ch);ch=getchar())x=*x+ch-'';
return x*f;
}
int main()
{
int k = read();
int d = - k % ;
int S = (k + d) / ;
cout << << endl;
rep(i, , ) cout << << " ";
cout << -d << " ";
cout << S + d << endl;
}

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 = , f = ; char ch = getchar();
for(;!isdigit(ch);ch=getchar())if(ch == '-')f = -f;
for(;isdigit(ch);ch=getchar())x = * x + ch - '';
return x * f;
}
const int mod = ,maxn = 1e5 + ;
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[], sz;
void calsum()
{
memset(sumf, , sizeof(sumf));
int cur = ;
dwn(i, r, l)
{
cur += b[i];
inc(sumf[sz + cur], f[i - ]);
}
rep(i, , sz + sz) inc(sumf[i], sumf[i - ]);
}
int query(int pos)
{
if(pos + sz < )return ;
return sumf[min(pos + sz, sz + sz)];
}
}bs[]; inline void update(int pos, int val)
{
f[pos] = val;
bs[bl[pos + ]].calsum();
} int query(int x)
{
int ans = bs[bl[x]].query(k), cursum = bs[bl[x]].sum;
dwn(i, bl[x]-, )
{
inc(ans, bs[i].query(k - cursum));
cursum += bs[i].sum;
}
return ans;
} int main()
{
n = read(), k = read();
rep(i, , n) a[i] = read();
rep(i, , n) nx[i] = cur[a[i]], cur[a[i]] = i;
f[] = ; int kk = sqrt(n);
rep(i, , n) bl[i] = (i - ) / kk + ;
rep(i, , bl[n])
{
bs[i].r = min(i * kk, n);
bs[i].l = bs[i-].r + ;
bs[i].sz = bs[i].r - bs[i].l + ;
}bs[].calsum();
rep(i, , 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] -= ;
bs[bl[pos]].sum -= ; bs[bl[pos]].calsum();
}
b[i]++; bs[bl[i]].sum++; bs[bl[i]].calsum();
update(i, (f[i] = query(i)));
}
cout << f[n] << endl;
}

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=,f=;char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())if(ch=='-')f=-f;
for(;isdigit(ch);ch=getchar())x=*x+ch-'';
return x*f;
}
int query(vector<int> s, vector<int> t, int node) {
cout << s.size() << endl;
for(int i = ; i < (int)s.size(); ++i) {
if(i != )putchar(' ');
cout << s[i] + ;
}
cout << endl;
cout << t.size() << endl;
for(int i = ; i < (int)t.size(); ++i) {
if(i != )putchar(' ');
cout << t[i] + ;
}
cout << endl;
cout << node + << 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 = ; i < n; ++i) nd.push_back(i);
p.resize(n);
for (int i = ; i < n; ++i) p[i] = i;
size.resize(n);
size[] = n;
for (int i = ; i < n; ++i) size[i] = query({ }, nd, i);
sort(p.begin(), p.end(), [](int x, int y) { return size[x] < size[y]; });
for (auto node : p) {
if (size[node] != ) {
while (!X.empty()) {
vector<int> cur(X.begin(), X.end());
if (!query({ }, cur, node)) break;
int l = , r = (int)cur.size();
while (l + < r) {
int mid = l + r >> ;
if (query({ }, 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 + << " " << p.second + << endl;
return ;
}

CF Round 542 Div1.的更多相关文章

  1. 【前行&赛时总结】◇第4站&赛时9◇ CF Round 513 Div1+Div2

    ◇第4站&赛时9◇ CF Round 513 Div1+Div2 第一次在CF里涨Rating QWQ 深感不易……作blog以记之 ( ̄▽ ̄)" +Codeforces 的门为你打 ...

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

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

  3. Codeforces Round #542 题解

    Codeforces Round #542 abstract I决策中的独立性, II联通块染色板子 IIIVoronoi diagram O(N^2 logN) VI环上距离分类讨论加取模,最值中的 ...

  4. CF Round #551 (Div. 2) D

    CF Round #551 (Div. 2) D 链接 https://codeforces.com/contest/1153/problem/D 思路 不考虑赋值和贪心,考虑排名. 设\(dp_i\ ...

  5. Codeforces Round #543 Div1题解(并不全)

    Codeforces Round #543 Div1题解 Codeforces A. Diana and Liana 给定一个长度为\(m\)的序列,你可以从中删去不超过\(m-n*k\)个元素,剩下 ...

  6. Codeforces Round #545 Div1 题解

    Codeforces Round #545 Div1 题解 来写题解啦QwQ 本来想上红的,结果没做出D.... A. Skyscrapers CF1137A 题意 给定一个\(n*m\)的网格,每个 ...

  7. Codeforces Round #539 Div1 题解

    Codeforces Round #539 Div1 题解 听说这场很适合上分QwQ 然而太晚了QaQ A. Sasha and a Bit of Relax 翻译 有一个长度为\(n\)的数组,问有 ...

  8. CF Round #510 (Div. 2)

    前言:没想到那么快就打了第二场,题目难度比CF Round #509 (Div. 2)这场要难些,不过我依旧菜,这场更是被\(D\)题卡了,最后\(C\)题都来不及敲了..最后才\(A\)了\(3\) ...

  9. Codeforces Round 542 (Div. 2)

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

随机推荐

  1. java中byte数组与int,long,short间的转换

    http://blog.csdn.net/leetcworks/article/details/7390731 package com.util; /** * * <ul> * <l ...

  2. Mac 环境 下使用Charles 抓包Http/Https请求

    实现目标 在Mac 上 对 iOS  真机 和 模拟器 进行 Http/Https抓包 使用工具 Mac 上 Charles 4.2  安装 参考链接 1. 和 链接 2. 抓包 http 请求 (1 ...

  3. webpack基础配置

    webpack运行规则: Webpack 会给每个模块分配一个唯一的id并通过这个id索引和访问模块.在页面启动时,会先执行入口文件中的代码,其它模块会在运行 require 的时候再执行. 运行时主 ...

  4. hadoop06---多线程

    .1.1. 实现线程的两种方式 1.继承Thread的方式 见代码MyThreadWithExtends 2.声明实现 Runnable 接口的方式 见代码MyThreadWithImpliment ...

  5. Model FEP 快易播看板推播系统

    主要特色: 低成本,快速导入 透过Wi-Fi 方式推播,现场架设容易 采Web Browser 介面登入操作,简单快速 模组化版面设定,弹性调整资料呈现方式 可整合多种连线方式与外部资料库沟通 可自行 ...

  6. cocos2dx打飞机项目笔记五:CCSpriteBatchNode 的使用

    在上一节里,在头文件看到 定义了一个 CCSpriteBatchNode* batchNode;,在addEnemy方法里看到 batchNode->addChild(enemy); 新建的敌机 ...

  7. Kubernetes List-Watch

    list-watch,作为k8s系统中统一的异步消息传递方式,对系统的性能.数据一致性起到关键性的作用. list-watch操作需要做这么几件事: 由组件向apiserver而不是etcd发起wat ...

  8. linux图形界面基本知识(X、X11、Xfree86、Xorg、GNOME、KDE之间的关系)

    linux图形界面基本知识(X.X11.Xfree86.Xorg.GNOME.KDE之间的关系)(转自互联网) LINUX初学者经常分不清楚linux和X之间,X和Xfree86之间,X和KDE,GN ...

  9. Linux嵌入式 -- 内核 - 进程控制 和 调度

    1. 进程四要素 1. 有一段程序供其执行.这段程序不一定是某个进程所专有,可以与其他进程共用. 2. 有进程专用的内核空间堆栈. 3. 在内核中有一个task_struct数据结构,即通常所说的&q ...

  10. 【转】Oracle中插入和取出图片(用BLOB类型)

    原文地址:http://czllfy.iteye.com/blog/66737 其他参考资料地址:http://lavasoft.blog.51cto.com/62575/321882/ 要在orac ...