Codeforces Round #773 (Div. 2)D,E
D. Repetitions Decoding
传送门
题目大意:
一个长为
n
(
n
2
≤
250000
)
n(n^2\leq250000)
n(n2≤250000)的序列,每个元素
a
i
(
1
≤
a
i
≤
1
0
9
)
a_{i}(1\leq a_{i}\leq 10^9)
ai(1≤ai≤109)
可以执行若干次操作,每次在序列中的某个位置插入两个相同的数字,给出一组操作序列,使得操作后的序列可以划分为若干个长为偶数的段,每段长度为
k
i
k_{i}
ki,在该段内满足
a
j
=
a
j
+
k
i
2
a_{j}=a_{j+\frac {k_{i}}{2}}
aj=aj+2ki,并给出最终各个段的长度,如果操作序列不存在,输出
−
1
-1
−1。
思路:
考虑到在执行操作的过程当中,每种数字个数的奇偶性不会发生变化,而最终的序列如果要满足要求,那么每种数字的个数必须都是偶数,于是当一开始存在某种数字的个数是奇数时,就不存在操作序列。
之后我们可以用以下的方法来进行构造,不断从前往后找一对相同的数字,假设找到的为
1
1
1,并且该序列为
1
1
1
2
2
2
3
3
3
1
1
1
.
.
.
...
... 那么我们可以在一对相同的数中的后一个的后面不断对称地插入位于这一对数之间的数字,之后序列变为
1
1
1
2
2
2
3
3
3
1
1
1
2
2
2
3
3
3
3
3
3
2
2
2
.
.
.
...
...,于是可以发现,
1
1
1
2
2
2
3
3
3
1
1
1
2
2
2
3
3
3就构成了一个合法的段,将它们拿掉后,序列变为
3
3
3
2
2
2
.
.
.
...
...,也就相当于删除了我们之前找到的一对数字,并将他们之间的数字翻转,于是重复这个步骤,就可以给出合法的操作序列了。显然这个步骤最多执行
n
2
\frac{n}{2}
2n次,每次执行需要
O
(
n
)
O(n)
O(n)的时间,所以可以在
O
(
n
2
)
O(n^2)
O(n2)内完成。
代码:
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
//#define int LL
#define lc p*2+1
#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#pragma warning(disable :4996)
const double eps = 1e-8;
const LL mod = 1000000007;
const LL MOD = 998244353;
const int maxn = 200010;
int T, N;
vector<int>A;
map<int, int>mp;
void solve()
{
for (auto& c : mp)
{
if (c.second % 2)
{
cout << -1 << endl;
return;
}
}
vector<PII>op;
vector<int>len;
int base = 0;
while(!A.empty())
{
auto beg = A.begin();
auto it2 = beg + 1;
while (*it2 != *beg)
it2++;
int num = it2 - beg;
if (it2 == beg + 1)
len.push_back(2);
else
{
len.push_back(num * 2);
auto tmp = beg + 1;
int pos = base + num + 1;
while (tmp != it2)
{
op.push_back(PII(pos++, *tmp));
tmp++;
}
reverse(A.begin(), it2);
}
A.erase(A.begin() + num - 1);
A.erase(A.begin() + num - 1);
base += num * 2;
}
cout << op.size() << endl;
for (auto& c : op)
cout << c.first << ' ' << c.second << endl;
cout << len.size() << endl;
for (auto& c : len)
cout << c << ' ';
cout << endl;
}
int main()
{
IOS;
cin >> T;
while (T--)
{
cin >> N;
A.clear(), mp.clear();
int num;
for (int i = 1; i <= N; i++)
{
cin >> num;
A.push_back(num);
mp[num]++;
}
solve();
}
return 0;
}
E. Anonymity Is Important
传送门
题目大意:
n
(
1
≤
n
≤
2
×
1
0
5
)
n(1\leq n\leq2\times10^5)
n(1≤n≤2×105)个人,编号
1
∼
n
1\sim n
1∼n,
q
(
1
≤
q
≤
2
×
1
0
5
)
q(1\leq q\leq2\times10^5)
q(1≤q≤2×105)次询问:
0
0
0
l
l
l
r
r
r
x
x
x:当
x
=
0
x=0
x=0时,表示
[
l
,
r
]
[l,r]
[l,r]内没有人生病;
x
=
1
x=1
x=1时,
[
l
,
r
]
[l,r]
[l,r]内至少
1
1
1个人生病。
1
1
1
j
j
j:回答第
j
j
j个人是否生病,无法确定则输出N/A
思路:
x
=
0
x=0
x=0 的情况我们很容易处理,用set
来维护所有尚未确定不会生病的人,对于每条
0
0
0
l
l
l
r
r
r
0
0
0 的信息,可以将
[
l
,
r
]
[l,r]
[l,r] 内所有人从set
中删去。
当查询到
j
j
j 时,如果
j
j
j 不在set
内,那么就可以确定
j
j
j 没有生病。否则
j
j
j 要么生病,要么状态无法确定。如果要确定
j
j
j 是生病的,必须在查询之前出现过一条形如
0
0
0
l
l
l
r
r
r
1
1
1 的信息,使得当前在
[
l
,
r
]
[l,r]
[l,r] 内,有且仅有
j
j
j 一个人仍在set
当中(如果多于一个说明每个人都有可能是病人,就无法判断了)。于是我们在set
中找到
j
j
j 的前驱
l
l
l 以及后继
r
r
r (可以在set
中额外加入
0
0
0 和
n
+
1
n+1
n+1 两个人便于实现),我们可以枚举所有位于
[
l
+
1
,
j
]
[l+1,j]
[l+1,j] 内的查询信息的左端点,来看是否有一个对应的右端点的值
<
r
<r
<r 即可(因为所有信息都合法,所以左右右端点的值都会
>
=
j
>=j
>=j ),这可以用线段树来高效解决。
用一个线段树来维护每个左端点区间对应的右端点的最小值,对于每条
0
0
0
l
l
l
r
r
r
1
1
1 的信息。我们将左端点
l
l
l处的值单点修改为
m
i
n
(
d
a
t
[
l
]
,
r
)
min(dat[l],r)
min(dat[l],r) 即可。在查询时只需要查询区间
[
l
+
1
,
j
]
[l+1,j]
[l+1,j] 即可,复杂度
O
(
(
n
+
q
)
l
o
g
n
)
O((n+q)logn)
O((n+q)logn)。
代码:
#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
//#define int LL
#define lc p*2+1
#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#pragma warning(disable :4996)
const double eps = 1e-8;
const LL mod = 1000000007;
const LL MOD = 998244353;
const int maxn = 200010;
int N, Q;
set<int>S;
struct {
int l, r, dat;
}tr[maxn * 4];
void build(int p, int l, int r)
{
tr[p].l = l, tr[p].r = r;
if (l + 1 == r)
{
tr[p].dat = inf;
return;
}
int mid = (l + r) / 2;
build(lc, l, mid), build(rc, mid, r);
tr[p].dat = min(tr[lc].dat, tr[rc].dat);
}
void modify(int p, int a, int x)
{
if (tr[p].l + 1 == tr[p].r)
{
tr[p].dat = min(tr[p].dat, x);
return;
}
int mid = (tr[p].l + tr[p].r) / 2;
if (a < mid)
modify(lc, a, x);
else
modify(rc, a, x);
tr[p].dat = min(tr[lc].dat, tr[rc].dat);
}
int query(int p, int l, int r)
{
if (tr[p].l >= l && tr[p].r <= r)
return tr[p].dat;
int mid = (tr[p].l + tr[p].r) / 2;
if (r <= mid)
return query(lc, l, r);
if (l >= mid)
return query(rc, l, r);
return min(query(lc, l, mid), query(rc, mid, r));
}
void solve()
{
build(0, 1, N + 1);
for (int i = 0; i <= N + 1; i++)
S.insert(i);
int type, l, r, x, j;
while (Q--)
{
cin >> type;
if (type == 0)
{
cin >> l >> r >> x;
if (x == 0)
{
while (!S.empty())
{
int pos = *S.lower_bound(l);
if (pos <= r)
S.erase(pos);
else
break;
}
}
else
modify(0, l, r);
}
else
{
cin >> j;
if (!S.count(j))
cout << "NO" << endl;
else
{
auto itl = S.lower_bound(j), itr = S.upper_bound(j);
itl--;
int l = *itl, r = *itr;
if (query(0, l + 1, j + 1) < r)
cout << "YES" << endl;
else
cout << "N/A" << endl;
}
}
}
}
int main()
{
IOS;
cin >> N >> Q;
solve();
return 0;
}
Codeforces Round #773 (Div. 2)D,E的更多相关文章
- Codeforces Round #415 (Div. 2)(A,暴力,B,贪心,排序)
A. Straight «A» time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...
- Codeforces Round #427 (Div. 2)—A,B,C,D题
A. Key races 题目链接:http://codeforces.com/contest/835/problem/A 题目意思:两个比赛打字,每个人有两个参数v和t,v秒表示他打每个字需要多久时 ...
- Codeforces Round #239 (Div. 1)C, 407C
题目链接:http://codeforces.com/contest/407/problem/C 题目大意:给一个长度为n的数列,m次操作,每次操作由(li, ri, ki)描述,表示在数列li到ri ...
- Codeforces Round #372 (Div. 2) A ,B ,C 水,水,公式
A. Crazy Computer time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- Codeforces Round #371 (Div. 2) A ,B , C 水,水,trie树
A. Meeting of Old Friends time limit per test 1 second memory limit per test 256 megabytes input sta ...
- Codeforces Round #725 (Div. 3) A-D,F题解
A. Stone Game 思路:总共3种情况,都从最左端被拿走,都从最右端被拿走,左侧的从最左端被拿走且右侧的从最右端被拿走,取最小值即可 代码: //CF-725.A #include<bi ...
- Codeforces Round #773 (Div. 2)
这一场打的非常一般,不过把D想出来了(当然只剩10min没有写出来). A.Hard Way 题意:(很怪的题,我读题读半天)给你一个三角形(端点都在整数点上),问从x轴往上划线(不一定垂直)画不到的 ...
- Codeforces Round #525 (Div. 2)
Codeforces Round #525 (Div. 2) 哎,忍不住想吐槽一下,又要准备训练,又要做些无聊的事,弄得我都想退出了. 好好的训练不好么???? 只能做出两道水题,其实C题,感觉做出来 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
随机推荐
- 一份尽可能全面的Go channel介绍
写在前面 针对目前网络上Go channel知识点较为分散(很难有单独的一份资料把所有知识点都囊括进来)的情况,在下斗胆站在巨人的肩膀上,总结了前辈的工作,并加入了自己的理解,形成了这篇文章.本文类似 ...
- openstack,docker,mesos,Kubernetes(k8s)
作者:张乾链接:https://www.zhihu.com/question/62985699/answer/204233732来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- linux中sort命令全面解析
目录 一:sort命令作用 二:sort格式 1.sort参数 2.参数解析 sort命令简介 Linux sort 命令用于将文本文件内容加以排序. sort 可针对文本文件的内容,以行为单位来排序 ...
- elasticsearch查询之大数据集分页查询
一. 要解决的问题 search命中的记录特别多,使用from+size分页,直接触发了elasticsearch的max_result_window的最大值: { "error" ...
- C++/WinUI 3 技术笔记(一)
微软在 Windows 10 Version 1809 上正式发布了新的 UI 框架,命名为 WinUI 3. 这已经是微软发布的第不知道多少个 UI 框架了,但是微软宣称它将支持原生 C++ 和 W ...
- 【h5游戏开发】egret引擎p2物理引擎 - 小球碰撞地面搞笑的物理现象
重力的方向和地面的问题 p2中默认的方向是从上到下,如果重力默认是正数的话,物体放到世界中是会从上面往下面飘的 p2中plane地面默认的方向是y轴的方向,而在p2中y轴的方向默认是从上往下 首先来看 ...
- IDEA使用MybatisCodeHelperPro插件
下载MybatisCodeHelperPro: 链接:https://pan.baidu.com/s/1H6csq9STVh0Ofldh6V6gxQ提取码:r2g3 IDEA安装本地插件: ctrl+ ...
- Android文件的权限概念
//通过context对象获取一个私有目录的文件读取流 /data/data/packagename/files/userinfoi.txt FileInputStream fileInputS ...
- ORA-22922:nonexistent LOB value问题及listagg()函数
1 现象及错误信息 在执行一次查询的过程,Oracle出现ORA-22922:nonexistent LOB value 的错误:根据提示,是在查询时没有找到lob对象: 2 问题分析 查看SQL,发 ...
- Redis常用数据类型以及操作
Redis常用数据类型以及操作 目录 Redis常用数据类型以及操作 一.String数据类型 1. SET/GET/APPEND/STRLEN 2. INCR/DECR/INCRBY/DECRBY ...