因为偷懒就只写G和H的题解了。

G - Modulo Shortest Path

首先可以观察到对于一条从点\(i\)到点\(j\)的边,权值只有两种:\(A_i+B_j\)和\(A_i+B_j-M\)。

那么我们假如把点按照\(B\)升序排成一列,那么当中的一个点肯定只会向前半部分连权值为\(A_i+B_j\)的边,后半部分连权值\(A_i+B_j-M\)的边。

我们可以把一个点拆成入点和出点(此时仍旧按照\(B\)升序排成两列),由出点向入点连权值为\(A_i+B_j\)和\(A_i+B_j-M\)的这两种边,入点向对应出点连接权值为\(0\)的边。

虽然此时边数仍旧是\(O(N^2)\)的,但是我们可以在每一个入点向下一个入点连一条权值为它们的\(B_i\)的差值的边,可以看成是一种反悔操作,走到入点了可以不走向出点,而是往下一个入点继续走,再走到对应的出点。这样发现没有必要给每一个点的出点连那么多条边出去了,只需要两条,一条连向序列开头的点,一条连向第一个使得权值和大于等于\(M\)的点。那么每一条原来的出点向入点连接的边都可以看成是一条现在出点向入点连接的边和一条入点构成的链的组合。

接下来只需要从起点到终点跑最短路就行了。

#include<bits/stdc++.h>
using namespace std; typedef long long ll; int n,m,S,T;
pair<pair<int,int>,int> a[200005];
vector<pair<int,int>> g[400005];
ll d[400005]; int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i].first.first;
for(int i=1;i<=n;i++)cin>>a[i].first.second,a[i].second=i;
sort(a+1,a+1+n,[](const pair<pair<int,int>,int> &a,const pair<pair<int,int>,int> &b){
if(a.first.second!=b.first.second)return a.first.second<b.first.second;
return a.second<b.second;
});
S=1;
while(a[S].second!=1)S++;
T=1;
while(a[T].second!=n)T++;
for(int i=1;i<n;i++){
g[n+i].emplace_back(n+i+1,a[i+1].first.second-a[i].first.second);
}
for(int i=1;i<=n;i++){
g[n+i].emplace_back(i,0);
g[i].emplace_back(n+1,a[i].first.first+a[1].first.second);
int l=1,r=n,mid,res=-1;
while(l<=r){
mid=l+r>>1;
if(a[i].first.first+a[mid].first.second>=m){
res=mid;
r=mid-1;
}else{
l=mid+1;
}
}
if(res!=-1)g[i].emplace_back(n+res,a[i].first.first+a[res].first.second-m);
}
priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<pair<ll,int>>> q;
q.emplace(0,S);
memset(d,0x3f,sizeof(d));
d[S]=0;
while(!q.empty()){
ll cd;
int x;
tie(cd,x)=q.top();
q.pop();
if(cd>d[x])continue;
for(auto &[y,z]:g[x])if(d[y]>cd+z){
q.emplace(d[y]=cd+z,y);
}
}
cout<<d[T]<<'\n'; return 0;
}

H - King's Tour

比赛时没有想到递归处理的我真是铸币呜呜呜

首先可以考虑只有两行或者只有两列的棋盘怎么处理,那么由于八向移动的特性可以这么处理(起点在左上角,红点为终点):

然后就考虑行数和列数都至少为\(3\)的情况(同样默认起点左上角),尝试走过最上方的一行,或者最左边的一列,由于终点一定不会在左上角,且行数和列数都大于\(2\),那么一定两种操作可以选做一种,并且做完以后剩下来没访问过的棋盘仍旧是满足起点在一个角上且终点不和起点相同位置。

然后递归处理即可。

#include<bits/stdc++.h>
using namespace std; vector<pair<int,int>> sol(int n,int m,int a,int b){
vector<pair<int,int>> r;
if(m==2){
for(int i=1;i<a;i++){
r.emplace_back(i,1);
r.emplace_back(i,2);
}
for(int i=a;i<=n;i++)r.emplace_back(i,b^3);
for(int i=n;i>=a;i--)r.emplace_back(i,b);
}else if(n>2&&(a>2||a==2&&b!=m)){
for(int i=1;i<=m;i++)r.emplace_back(1,i);
for(auto &[x,y]:sol(n-1,m,a-1,m+1-b))r.emplace_back(x+1,m+1-y);
}else{
r=sol(m,n,b,a);
for(auto &[x,y]:r)swap(x,y);
}
return r;
} int main(){ ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); int n,m,a,b;
cin>>n>>m>>a>>b;
for(auto &[x,y]:sol(n,m,a,b))cout<<x<<' '<<y<<'\n'; return 0;
}

M-SOLUTIONS Programming Contest 2021(AtCoder Beginner Contest 232) 题解的更多相关文章

  1. AtCoder Beginner Contest 076

    A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...

  2. atcoder beginner contest 251(D-E)

    Tasks - Panasonic Programming Contest 2022(AtCoder Beginner Contest 251)\ D - At Most 3 (Contestant ...

  3. AtCoder Beginner Contest 100 2018/06/16

    A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...

  4. KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解

    KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...

  5. AtCoder Beginner Contest 184 题解

    AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...

  6. AtCoder Beginner Contest 255(E-F)

    Aising Programming Contest 2022(AtCoder Beginner Contest 255) - AtCoder E - Lucky Numbers 题意: 给两个数组a ...

  7. AtCoder Beginner Contest 052

    没看到Beginner,然后就做啊做,发现A,B太简单了...然后想想做完算了..没想到C卡了一下,然后还是做出来了.D的话瞎想了一下,然后感觉也没问题.假装all kill.2333 AtCoder ...

  8. AtCoder Beginner Contest 053 ABCD题

    A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...

  9. AtCoder Beginner Contest 136

    AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...

随机推荐

  1. [bzoj1146]网络管理

    发现是链上的问题,所以树链剖分发现要查询第k大,因为第k大不支持合并,所以要二分答案二分答案后相当于询问一些区间内大于某数的数个数,直接线段树套平衡树即可时间复杂度$o(nlog^{4}_n)$(跟$ ...

  2. [atARC107F]Sum of Abs

    价值即等价于给每一个点系数$p_{i}=\pm 1$,使得$\forall (x,y)\in E,p_{x}=p_{y}$的最大的$\sum_{i=1}^{n}p_{i}b_{i}$ 如果没有删除(当 ...

  3. GeoServer style 配置样例

    <?xml version="1.0" encoding="UTF-8"?> <StyledLayerDescriptor version=& ...

  4. ☕【Java深层系列】「技术盲区」让我们一起完全吃透针对于时间和日期相关的API指南

    技术简介 java中的日期处理一直是个问题,没有很好的方式去处理,所以才有第三方框架的位置比如joda.文章主要对java日期处理的详解,用1.8可以不用joda. 时间概念 首先我们对一些基本的概念 ...

  5. 洛谷 P3781 - [SDOI2017]切树游戏(动态 DP+FWT)

    洛谷题面传送门 SDOI 2017 R2 D1 T3,nb tea %%% 讲个笑话,最近我在学动态 dp,wjz 在学 FWT,而我们刚好在同一天做到了这道题,而这道题刚好又是 FWT+动态 dp ...

  6. Matlab 代码注释

    Matlab 代码注释 一直在找类似doxygen一样将程序注释发表成手册的方法,现在发现,Matlab的publish功能自己就能做到. Publish 简介 并非所有注释都能作为文本进行输出,MA ...

  7. 如何根据taxid(或taxname)快速获得taxname(或taxid)?

    目录 需求 实现 需求 我有一个物种taxonomy ID的list,想获得相应的物种名,不要一个个去NCBI Taxonomy官网查.反之根据物种名list查询对应的taxid. 实现 因为之前没怎 ...

  8. PHP非对称加密-RSA

    对称加密算法是在加密和解密时使用同一个密钥.与对称加密算法不同,非对称加密算法需要两个密钥--公开密钥(public key)和私有密钥(private key)进行加密和解密.公钥和密钥是一对,如果 ...

  9. OOM机制

    Linux内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没有实际全部使用,为了提高性能,这部分没用的内存可以留作它用,这部分内存是属于每个进程的,内核直接回收利用的话比较麻烦,所以内 ...

  10. Django创建多对多表关系的三种方式

    方式一:全自动(不推荐) 优点:django orm会自动创建第三张表 缺点:只会创建两个表的关系字段,不会再额外添加字段,可扩展性差 class Book(models.Model): # ... ...