Educational Codeforces Round 102 (Rated for Div
Educational Codeforces Round 102 (Rated for Div. 2)
No More Inversions
给定\(k\),序列\(a\)长度为\(n\):\(1,2,3...k,k-1,k-2...k-(n-k)\),设序列\(a\)中逆序数为\(m\),给定排列\(p:1,2,3...k\),利用该排列形成新的序列\(b:b[i]= p[a[i]]\), 请你构造排列\(p\)使得序列\(b\)的逆序数不超过\(m\),且序列\(b\)字典序最大
题解:构造 + 思维 + 回文串的逆序对 : 记一下结论
引理:长度相同且元素不重复的回文串(\([s_1,s_2...s_k...s_2,s_1]\))逆序对恒定相等,其逆序数为\((k-1)^2\)
证明:
任选\(s_i,i<=k-1\),那么\(s_i...s_k...s_i\)三个之间一定会形成一个逆序对,那么这样的组合一共有\(k-1\)个,所以一定会产生\(k-1\)个逆序对
任选\(s_i,s_j且i,j<=k-1\),那么\(s_i...s_j...s_j...s_i\)四个之间一定会形成两个逆序对,那么这样的组合一共有\(C_{k-1}^{2}\)个,所以一定会产生\(2*C_{k-1}^{2}\)个逆序对
那么最终合并两种情况产生的逆序对,总共产生\((k-1)^2\)个逆序对
我们发现对于任意排列\(p\),假设\(p:[1,2,3,4]\),\(n=6\),那么序列\(b\)一定是\([1,2,3,4,3,2]\),也就是说\([k-(n-k),n]\)之间一定形成回文串,我们发现对于序列\(a\)而言,恰好也是在\([k-(n-k),n]\)之间形成回文串,根据引理得知两者之间逆序数相同,因为序列\(b\)的逆序数不能超过序列\(a\),所以对于序列\(b\)而言\([1,k-(n-k)-1]\)一定不能产生逆序对,也就是说前面一定为\(1,2,3...k-(n-k)-1\),那么如果想要使得字典序最大我们只要使得排列\(p\)在\([k-(n-k),k]\)中翻转即可,例如上述样例\(p:[1,4,3,2],b:[1,4,3,2,3,4]\)
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10;
int n, k;
void solve()
{
cin >> n >> k;
for (int i = 1; i <= (k - (n - k) - 1); ++i)
cout << i << " ";
for (int i = k; i >= (k - (n - k)); --i)
cout << i << " ";
cout << endl;
}
signed main(void)
{
Zeoy;
int T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
Program
一共有\(n\)次操作,\(x\)初始值为\(0\),每次操作可以使\(x\)加1或减1,现在给出\(m\)次询问,每次询问给出\(l,r\),要求不执行\([l,r]\)之间的操作,让你给出如果只执行其他操作的话一共\(x\)会出现多少个不同的值
题解:前缀/后缀维护最值
我们思考如何得出答案:我们只要知道这些操作之中\(x\)的最大值和最小值就能知道出现多少个不同的值
我们只需要将每次操作看成-1或1,得到前缀和\(pre\),然后维护\(pre\)的前缀以及后缀最大值、最小值
对于询问\([l,r]\)来说,首先\([1,l-1]\)之间的最大值和最小值不会受到影响,但是\([r+1,n]\)之间的最大值和最小值会受到影响,实际上模拟后发现只需要在后缀最大值和最小值中减去\(pre[r]-pre[l-1]\)就能消除影响
本题也可以通过线段树维护区间最值求解,消除影响也是通过减去\(pre[r]-pre[l-1]\)
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10;
int n, q;
int pre[N];
int pre_min[N], pre_max[N];
int suf_min[N], suf_max[N];
void solve()
{
cin >> n >> q;
string s;
cin >> s;
s = " " + s;
for (int i = 1; i <= n; ++i)
{
if (s[i] == '-')
pre[i] = pre[i - 1] - 1;
else
pre[i] = pre[i - 1] + 1;
pre_min[i] = min(pre_min[i - 1], pre[i]);
pre_max[i] = max(pre_max[i - 1], pre[i]);
}
suf_max[n + 1] = suf_min[n + 1] = pre[n];
for (int i = n; i >= 1; i--)
{
suf_min[i] = min(suf_min[i + 1], pre[i]);
suf_max[i] = max(suf_max[i + 1], pre[i]);
}
while (q--)
{
int l, r;
cin >> l >> r;
int sum = pre[r] - pre[l - 1];
int maxx = max(pre_max[l - 1], suf_max[r + 1] - sum);
int minn = min(pre_min[l - 1], suf_min[r + 1] - sum);
cout << maxx - minn + 1 << endl;
}
}
signed main(void)
{
Zeoy;
int T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
Minimum Path
现给定有权无向图,\(n\)个点,\(m\)条边,定义两点之间路径的权值为:路径上所有边的权值之和\(-\)路径上的最大边权\(+\)路径上的最小边权;先让你求出原点\(1\)到其他每个节点路径的最小权值
题解:分层图最短路
因为要求的是路径最小权值,我们贪心的想删去最大权值边和加上最小权值边,我们将题目转化为删去任意一条边然后一条边加上两次,那么我们实现加减操作可以建立分层图:
- 建立四层图(将每个点拆成4个),每层正常建边
- 连接第一层到第二层的边权为\(0\),代表删去一条边
- 连接第二层到第四层(答案层)的边权为\(2*w\),代表一条边加上两次
- 但是第三层有什么用呢?实际上我们前面分层情况代表了先出现最大边后出现最小边,但是另一种情况就是先出现最小边再出现最大边,所以我们连接第一层到第三层的边权为\(2*w\),连接第三层到第四层(答案层)的边权为\(0\)
- 最后答案就在第四层,但是需要注意有些点和\(1\)直接相连,那么它既作为最大值也作为最小值,最后路径权值就等于路径上边权之和,所以我们需要特判一下\(min(dis[i],dis[i+3*n])\)
建完图后跑一遍\(dij\)即可
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10;
int n, m;
vector<pii> g[N << 2];
int dis[N << 2];
int vis[N << 2];
void dij(int st)
{
for (int i = 1; i <= 4 * n; ++i)
dis[i] = INF;
dis[st] = 0;
priority_queue<pii, vector<pii>, greater<pii>> q;
q.push({dis[st], st});
while (q.size())
{
int u = q.top().second;
q.pop();
if (vis[u])
continue;
vis[u] = 1;
for (auto [v, w] : g[u])
{
if (dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
q.push({dis[v], v});
}
}
}
}
void solve()
{
cin >> n >> m;
for (int i = 1, u, v, w; i <= m; ++i)
{
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
g[u + n].push_back({v + n, w});
g[v + n].push_back({u + n, w});
g[u + 2 * n].push_back({v + 2 * n, w});
g[v + 2 * n].push_back({u + 2 * n, w});
g[u + 3 * n].push_back({v + 3 * n, w});
g[v + 3 * n].push_back({u + 3 * n, w});
g[u].push_back({v + n, 0});
g[v].push_back({u + n, 0});
g[u].push_back({v + 2 * n, 2 * w});
g[v].push_back({u + 2 * n, 2 * w});
g[u + n].push_back({v + 3 * n, 2 * w});
g[v + n].push_back({u + 3 * n, 2 * w});
g[u + 2 * n].push_back({v + 3 * n, 0});
g[v + 2 * n].push_back({u + 3 * n, 0});
}
dij(1);
for (int i = 2; i <= n; ++i)
cout << min(dis[i], dis[i + 3 * n]) << " ";
cout << endl;
}
signed main(void)
{
Zeoy;
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}
Educational Codeforces Round 102 (Rated for Div的更多相关文章
- Educational Codeforces Round 102 (Rated for Div. 2)
比赛地址 A(水题) 题目链接 题目: 给出一个数组\(a\)并能进行一个操作使得数组元素更改为数组任意其他两元素之和,问是否可以让数组元素全部小于等于\(d\) 解析: 排序后判断最大值是否小于等于 ...
- Educational Codeforces Round 102 (Rated for Div. 2) D. Program (思维,前缀和)
题意:给你一个只含\(+\)和\(-\)的字符串,给你一个数\(x\),\(x\)初始为\(0\),随着字符串的遍历会加一减一,现在有\(m\)个询问,每个询问给出一个区间\([l,r]\)表示将这个 ...
- Educational Codeforces Round 102 (Rated for Div. 2) B. String LCM (构造,思维)
题意:给你两个字符串\(a\)和\(b\),找出它们的\(lcm\),即构造一个新的字符串\(c\),使得\(c\)可以由\(x\)个\(a\)得到,并且可以由\(y\)个\(b\)得到,输出\(c\ ...
- Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship
Problem Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...
- Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)
Problem Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...
- Educational Codeforces Round 43 (Rated for Div. 2)
Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...
- Educational Codeforces Round 35 (Rated for Div. 2)
Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...
- Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...
- Educational Codeforces Round 63 (Rated for Div. 2) 题解
Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...
随机推荐
- (零) React Native 项目开发拾遗
一位离职的前端同事,最近接了个 React Native 的活儿,遇到许多搞不定的问题,于是找到我帮忙"补课"(没有系统的学习 React Native,也不具备原生 Androi ...
- Linux下载安装jdk1.8
Linux下载安装jdk1.8 一.下载 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=a ...
- 深入理解Java对象结构
一.Java对象结构 实例化一个Java对象之后,该对象在内存中的结构是怎么样的?Java对象(Object实例)结构包括三部分:对象头.对象体和对齐字节,具体下图所示 1.Java对象的三部分 (1 ...
- jQuery父子页面之间元素、方法获取、调用
资源来自:https://www.cnblogs.com/it-xcn/p/5896231.html 一.jquery 父.子页面之间页面元素的获取,方法的调用: 1. 父页面获取子页面元素: 格式: ...
- 数据库周刊29│2020数据库研究报告;Oracle取消今年技术大会;腾讯云DBbridge发布支持一键迁库;饿了么迁至阿里云;PG数组查询;Oracle被比特币勒索;DM8 安全管理…
摘要:墨天轮数据库周刊第29期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.快讯:2020年Oracle OOW大会因疫情取消 系近20年首度[摘要]Oracle ...
- 15 Transformer 框架概述
博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...
- sqlplus登录脚本glogin.sql的配置
DEFINE sqlprompt=SQL COLUMN sqlprompt NEW_VALUE sqlprompt SET TERMOUT OFF SELECT USER || '@' || NVL( ...
- SegmentFault 基于 Kubernetes 的容器化与持续交付实践
本文是根据 KubeSphere 云原生 Meetup 杭州站讲师祁宁分享内容整理而成. SegmentFault 是一家综合性技术社区,由于它的内容跟编程技术紧密相关,因此访问量的波动也和这一群体的 ...
- 元类、实现ORM
阅读目录: 元类 元类实现ORM 元类 1. 类也是对象 在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Python中这一点仍然成立: >>> class Obj ...
- ansible批量部署apache
ansible批量部署apache 目录 ansible批量部署apache 安装ansible 基于ansible进行基础准备 配置受控端本地软件仓库 安装受控端Apache(httpd)的最新版本 ...