Codeforces Round #844 (Div. 1 + Div. 2, based on VK Cup 2022 - Elimination Round) 小记
在机房其它人都有许多的橙名小号后我终于大号上橙了(果然还是太菜了),写篇博客记录一下。
计数水平太弱,赛场最后 5 分钟乱糊了一个 F 的做法,后来发现其它人做法都短好多。
A & B & C
模拟即可。
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T=int>
T read(){
char c=getchar();T x=0;
while(c<48||c>57) c=getchar();
do x=(x<<1)+(x<<3)+(c^48),c=getchar();
while(c>=48&&c<=57);
return x;
}
void solve(){
ll w=read(),d=read(),h=read();
ll a=read(),b=read(),f=read(),g=read();
printf("%lld\n",h+min({abs(a-w)+abs(b-g)+abs(w-f),abs(a-0)+abs(b-g)+abs(f-0),abs(a-f)+abs(b-0)+abs(g-0),abs(a-f)+abs(b-d)+abs(g-d)}));
}
int main(){
int tc=read();
while(tc--) solve();
return 0;
}
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T=int>
T read(){
char c=getchar();T x=0;
while(c<48||c>57) c=getchar();
do x=(x<<1)+(x<<3)+(c^48),c=getchar();
while(c>=48&&c<=57);
return x;
}
const int N=1000003;
int n;
int a[N];
void solve(){
n=read();
for(int i=0;i<=n;++i) a[i]=0;
for(int i=1;i<=n;++i) ++a[read()];
for(int i=1;i<=n;++i) a[i]+=a[i-1];
int res=0;
for(int x=0;x<=n;++x){
int t=a[max(x-1,0)];
if(t==x&&(!x||a[x]==a[x-1])) ++res;
}
printf("%d\n",res);
}
int main(){
int tc=read();
while(tc--) solve();
return 0;
}
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T=int>
T read(){
char c=getchar();T x=0;
while(c<48||c>57) c=getchar();
do x=(x<<1)+(x<<3)+(c^48),c=getchar();
while(c>=48&&c<=57);
return x;
}
const int N=1000003;
int n;
char s[N];
void solve(){
scanf("%d%s",&n,s+1);
vector<int> c(26,0);
vector<pii> t(26);
for(int i=1;i<=n;++i) ++c[s[i]-97];
for(int i=0;i<26;++i) t[i]=pii(c[i],i);
sort(t.begin(),t.end(),greater<pii>());
ll res=1e18;
int pos=0;
for(int x=1;x<=26;++x){
if(n%x) continue;
ll ans=0;
for(int i=0;i<26;++i){
if(n/x<t[i].fi) ans+=t[i].fi-n/x;
}
for(int i=x;i<26;++i) ans+=t[i].fi;
if(ans<res) pos=x,res=ans;
}
vector<int> pp(26,0),stk;
for(int i=0;i<26;++i){
if(t[i].fi>n/pos)
pp[t[i].se]=t[i].fi-n/pos;
else if(i>=pos)
pp[t[i].se]=t[i].fi;
else{
int tt=n/pos-t[i].fi;
while(tt--) stk.emplace_back(t[i].se);
}
}
printf("%lld\n",res);
for(int i=1;i<=n;++i){
if(pp[s[i]-97]){
--pp[s[i]-97];
putchar(stk.back()+97);
stk.pop_back();
}
else putchar(s[i]);
}
putchar('\n');
}
int main(){
int tc=read();
while(tc--) solve();
return 0;
}
D
经典 +x 问题,考虑作差找不变量 \(a_i-a_j\),分解之后解出所有可能的 \(x\) check 即可。
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T=int>
T read(){
char c=getchar();T x=0;
while(c<48||c>57) c=getchar();
do x=(x<<1)+(x<<3)+(c^48),c=getchar();
while(c>=48&&c<=57);
return x;
}
int A[103];
int n;
set<ll> s[103];
void proc(int x,int y){
int t=A[y]-A[x];
for(int i=1;i*i<=t;++i)
if(t%i==0){
int a=i,b=t/i;
if((a^b)&1) continue;
ll p=(b-a)/2;
ll q=(b+a)/2;
p*=p;q*=q;
if(q>=A[y]&&p>=A[x]){
s[y].emplace(q-A[y]);
s[x].emplace(p-A[x]);
}
}
}
map<ll,int> mp;
void solve(){
n=read();
for(int i=1;i<=n;++i) A[i]=read(),s[i].clear();
int res=1;
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j) proc(i,j);
mp.clear();
for(int i=1;i<=n;++i)
for(ll x:s[i]) ++mp[x];
for(pair<ll,int> cur:mp) res=max(res,cur.se);
printf("%d\n",res);
}
int main(){
int tc=read();
while(tc--) solve();
return 0;
}
E
猜测答案为矩形之并。
考虑一维也就是区间怎么做,如果是按左端点/右端点排序的话不好扩展,任意顺序考虑这样做:对左/右端点维护一个 set,每次加入一个区间删除被严格包含的所有区间,然后把区间设为前驱的右端点 +1 和后继的左端点 -1。
于是我们先对第二维为 \([1,2]\) 的区间跑一边上述做法,然后再对 \([1,1],[2,2]\) 与 \([1,2]\) 一起分别跑即可。
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T=int>
T read(){
char c=getchar();T x=0;
while(c<48||c>57) c=getchar();
do x=(x<<1)+(x<<3)+(c^48),c=getchar();
while(c>=48&&c<=57);
return x;
}
const int N=400003;
struct rect{
int u,d,l,r,id;
}s[N];
bool cmp(rect x,rect y){return x.r<y.r;}
bool cmpid(rect x,rect y){return x.id<y.id;}
set<pii> o;
void solve(){
int n=read();
for(int i=1;i<=n;++i){
s[i].u=read();
s[i].l=read();
s[i].d=read();
s[i].r=read();
s[i].id=i;
}
sort(s+1,s+n+1,cmp);
o.clear();
for(int i=1;i<=n;++i){
if(s[i].u==1&&s[i].d==2){
if(s[i].l<=s[i].r){
set<pii>::iterator it=o.lower_bound(pii(s[i].l,0));
while(it!=o.end()&&it->fi<=s[i].r){
if(s[it->se].r>s[i].r){s[i].r=it->fi-1;break;}
else{s[it->se].u=2;s[it->se].d=1;o.erase(it);}
it=o.lower_bound(pii(s[i].l,0));
}
it=o.lower_bound(pii(s[i].l,0));
if(it!=o.begin()) s[i].l=max(s[i].l,s[prev(it)->se].r+1);
}
if(s[i].l<=s[i].r) o.emplace(s[i].l,i);
}
}
o.clear();
for(int i=1;i<=n;++i) if(s[i].u==1&&s[i].d==2&&s[i].l<=s[i].r) o.emplace(s[i].l,i);
for(int i=1;i<=n;++i){
if(s[i].u==1&&s[i].d==1){
if(s[i].l<=s[i].r){
set<pii>::iterator it=o.lower_bound(pii(s[i].l,0));
while(it!=o.end()&&it->fi<=s[i].r){
if(s[it->se].r>s[i].r){s[i].r=it->fi-1;break;}
else{s[it->se].u=2;o.erase(it);}
it=o.lower_bound(pii(s[i].l,0));
}
it=o.lower_bound(pii(s[i].l,0));
if(it!=o.begin()) s[i].l=max(s[i].l,s[prev(it)->se].r+1);
}
if(s[i].l<=s[i].r) o.emplace(s[i].l,i);
}
}
o.clear();
for(int i=1;i<=n;++i) if(s[i].u==1&&s[i].d==2&&s[i].l<=s[i].r) o.emplace(s[i].l,i);
for(int i=1;i<=n;++i){
if(s[i].u==2&&s[i].d==2){
if(s[i].l<=s[i].r){
set<pii>::iterator it=o.lower_bound(pii(s[i].l,0));
while(it!=o.end()&&it->fi<=s[i].r){
if(s[it->se].r>s[i].r){s[i].r=it->fi-1;break;}
else{s[it->se].d=1;o.erase(it);}
it=o.lower_bound(pii(s[i].l,0));
}
it=o.lower_bound(pii(s[i].l,0));
if(it!=o.begin()) s[i].l=max(s[i].l,s[prev(it)->se].r+1);
}
if(s[i].l<=s[i].r) o.emplace(s[i].l,i);
}
}
sort(s+1,s+n+1,cmpid);
long long res=0;
for(int i=1;i<=n;++i){
if(s[i].u<=s[i].d&&s[i].l<=s[i].r)
res+=(s[i].d-s[i].u+1)*(s[i].r-s[i].l+1);
}
printf("%lld\n",res);
for(int i=1;i<=n;++i){
if(s[i].u<=s[i].d&&s[i].l<=s[i].r){
printf("%d %d %d %d\n",s[i].u,s[i].l,s[i].d,s[i].r);
}
else puts("0 0 0 0");
}
}
int main(){
int tc=read();
while(tc--) solve();
return 0;
}
拒绝当口胡型选手。
首先原题过程发现有点难以维护,考虑直接对最终的括号串进行 DP。
我们将同一次操作插入的两个字符串匹配,在最终的括号串中发现这也是一个”括号串“的结构。
假设对于一个最终串,我们同时 DP 出了它的字符状态和匹配状态,那么原问题的结果应当是插入这些匹配的顺序乘这种方案数。
注意这些匹配是不能随便插入的,如 \(\texttt{)()(}\),第一个字符和第四个字符构成的匹配必须比中间的匹配先插入。
这些匹配是一个树形结构,那么插入顺序的方案数相当于树形拓扑序方案数 \(n!\prod_{i=1}^n \frac{1}{size_i}\),将 \(\frac{1}{size_i}\) 放入 DP 中统计即可。
具体怎么 DP:考虑每次在首尾加入一对 \(\texttt{)(}\) 或 \(\texttt{()}\),对于中间那段括号串的影响相当于将其前缀和折线整体上移/整体下移。
设 \(g_{i,j}\) 表示长度为 \(2i\) 的且首尾一定是一对匹配的括号串(不一定合法),其前缀和最小值为 \(j\) 的方案数。
\(f_{i,j}\) 表示若干个 \(g_{i,j}\) 中的串拼起来,长度为 \(2i\),前缀和最小值为 \(j\) 的方案数。
前后加匹配:\(\frac{pf_{i,x}}{i+1}\to g_{i+1,x+1}\) 和 \(\frac{(1-p)f_{i,x}}{i+1}\to g_{i+1,x-1}\)
拼接两个串的转移: \(f_{i,x}g_{j,y}\to f_{i+j,\min(x,y)}\),前缀和优化一下。
最后别忘了除以总方案变成概率以及乘上 \(n!\)。
总复杂度 \(O(n^3)\)。
#include <cstdio>
#include <algorithm>
using namespace std;
int read(){
char c=getchar();int x=0;
while(c<48||c>57) c=getchar();
do x=(x<<1)+(x<<3)+(c^48),c=getchar();
while(c>=48&&c<=57);
return x;
}
const int N=503,P=998244353;
typedef long long ll;
int qp(int a,int b=P-2){
int res=1;
while(b){
if(b&1) res=(ll)res*a%P;
a=(ll)a*a%P;b>>=1;
}
return res;
}
int f[N][N],g[N][N],dp[N][N],h[N],inv[N];
int n,p;
void inc(int &x,int v){if((x+=v)>=P) x-=P;}
int pref[N][N],preg[N][N],res[N];
void convol(int t){
for(int i=0;i<=t;++i)
for(int j=0;j<=t;++j){
pref[i][j]=f[i][j];
preg[i][j]=g[i][j];
if(j){
inc(pref[i][j],pref[i][j-1]);
inc(preg[i][j],preg[i][j-1]);
}
}
for(int i=0;i<t;++i)
for(int j=0;j<=t;++j){
inc(f[t][j],(ll)pref[i][j]*g[t-i][j]%P);
if(j) inc(f[t][j],(ll)preg[t-i][j-1]*f[i][j]%P);
}
}
int main(){
n=read();p=(ll)read()*qp(10000)%P;inv[1]=1;
for(int i=2;i<=n;++i) inv[i]=(ll)inv[P%i]*(P-P/i)%P;
int res=1;
f[0][0]=1;
for(int i=1;i<=n;++i){
for(int j=0;j<i;++j){
inc(g[i][max(j-1,0)],(ll)f[i-1][j]*p%P*inv[i]%P);//()
inc(g[i][j+1],(ll)f[i-1][j]*(P+1-p)%P*inv[i]%P);//)(
}
convol(i);
res=(ll)res*i%P*qp(i+i-1)%P;
}
res=(ll)res*f[n][0]%P;
printf("%d\n",res);
return 0;
}
Codeforces Round #844 (Div. 1 + Div. 2, based on VK Cup 2022 - Elimination Round) 小记的更多相关文章
- Codeforces Round #844 (Div. 1 + Div. 2, based on VK Cup 2022 - Elimination Round) A-D
比赛链接 A 题意 设计一条线路要贴着6个墙面走,从 \((a,b)\) 到 \((f,g)\) ,线路长度最短. 题解 知识点:模拟. 分类取最短即可. 时间复杂度 \(O(1)\) 空间复杂度 \ ...
- Codeforces Round #623 (Div. 1, based on VK Cup 2019-2020 - Elimination Round, Engine)A(模拟,并查集)
#define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; pair<]; bool cmp( ...
- Codeforces Round #623 (Div. 2, based on VK Cup 2019-2020 - Elimination Round, Engine)
A. Dead Pixel(思路) 思路 题意:给我们一个m*n的表格,又给了我们表格中的一个点a,其坐标为(x, y),问在这个表格中选择一个不包括改点a的最大面积的矩形,输出这个最大面积 分析:很 ...
- Codeforces Round 623(Div. 2,based on VK Cup 2019-2020 - Elimination Round,Engine)D. Recommendations
VK news recommendation system daily selects interesting publications of one of n disjoint categories ...
- Codeforces Round #623 (Div. 2, based on VK Cup 2019-2020 - Elimination Round, Engine) C. Restoring
C. Restoring Permutation time limit per test1 second memory limit per test256 megabytes inputstandar ...
- Codeforces Round #623 (Div. 2, based on VK Cup 2019-2020 - Elimination Round, Engine) B. Homecoming
After a long party Petya decided to return home, but he turned out to be at the opposite end of the ...
- Codeforces Round #623 (Div. 2, based on VK Cup 2019-2020 - Elimination Round, Engine) A Dead Pixel
讨论坏点的左右上下的矩形大小. #include <bits/stdc++.h> using namespace std; int main() { int t; cin >> ...
- Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals)
Codeforces Round #423 (Div. 1, rated, based on VK Cup Finals) A.String Reconstruction B. High Load C ...
- Codeforces 1023 A.Single Wildcard Pattern Matching-匹配字符 (Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Fi)
Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Patter ...
- Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 菜鸡只会ABC!
Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 全场题解 菜鸡只会A+B+C,呈上题解: A. Bear and ...
随机推荐
- 解决定时任务crontab运行待top的脚本
脚本编写如: #!/bin/bash /usr/bin/top -n -1 -u mysql > /root/script/log/$(date +"%Y%m%d_%H%M%S&quo ...
- ArcEngine(平板电脑墨迹错误代码。多次调用 RtpEnabled (异常来自 HRESULT:0x80040239))问题未有效解决
测试数据库中的要素无法执行ITopologicOperater接口下的方法,错误如图 暂记,错误未解决 tip: 1.随便移动一个节点 也不报错/ 2.手动按照他的节点画一个也不报错 3.bufer参 ...
- appium 怎么就一直连接不上设备呢
- 关于Go语言的底层,你想知道的都在这里!
目录 1. GoLang语言 1.1 Slice 1.2 Map 1.3 Channel 1.4 Goroutine 1.5 GMP调度 1.6 垃圾回收机制 1.7 其他知识点 2. Web框架Gi ...
- VSCode 快捷键,简化操作
一. 区域代码快捷键 1. 折叠所有 折叠所有区域代码的快捷: ctrl + k ctrl + 0 ; 展开所有折叠区域代码的快捷:ctrl +k ctrl + J ; 2. 按层 ...
- 针对于Sql server突然连接不到服务器的解决方法
问题叙述 点击连接之后,总是会弹出一个错误弹窗: 方法解决 快捷键Win+R,输入services.msc,进入到服务界面: 找到SQL 代理(DEV) 将手动打开改成自动 再连接试一次 连上啦! ( ...
- P4555 [国家集训队]最长双回文串 回文树(回文自动机)简单题
贴个题目链接:https://www.luogu.org/problem/P4555 题目:输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(∣X∣,∣Y∣≥1)且X和Y都是回文 ...
- 一款基于js/jquery标签拖拽排序小组件
这是一个基于jQuery写的拖拽小组件,写了大概两三天,刚好可以在前端方面练练手.拖拽原理是使用绝对定位+鼠标元素位置实现. GitHub地址:https://water1996.github.io/ ...
- 穷人版生产力工具,好用得飞起 「GitHub 热点速览」
被 GPT 和 OpenAI 刷屏了一个多月,现在 GitHub Trending 已经没有什么和 gpt 无关的项目了,但是好在总有优秀的开源项目拯救我的项目疲惫.像是贴心好用的反向代理 pgrok ...
- redis 5种数据类型的增删改查
string: 增:set name zhangsan 删:del name 改:set name lisi 查:get name hash: 增:hmset name name1 zhangsan ...