首页 > 其他分享 >CF677D Vanya and Treasure

CF677D Vanya and Treasure

时间:2023-09-16 18:55:41浏览次数:34  
标签:Vanya typedef nm int Treasure CF677D long include define

这题纯大力搞过去的,没用到啥技巧,后面看了下别人的做法发现还是很有意思的

我的做法就很粗暴,考虑令\(f_{i,j}\)表示走到\((i,j)\)的最短路,转移的话不难发现是个分层图DP

但是有一个显然的问题是当相邻两层间的点数很多时,暴力做的话会退化成\(O(n^2\times m^2)\),因此需要优化

像这种绝对值的式子一眼拆绝对值,不妨根据转移位置相对于现在位置的方向分四种情况讨论,那么对于每个点的转移相当于一个矩阵取\(\min\)的操作

可以直接用树套树做到\(O(nm\times\log (nm))\),但这题数据范围不大,因此可以每行开树状数组做到\(O(n^2m\times \log m)\),这样代码也比较好写

而高妙一点的做法是利用根号分治,当相邻两层的点数乘积比较小时就暴力转移,否则可以跑一个\(O(nm)\)的多源最短路,这样平衡过后总复杂度就是\(O(nm\times \sqrt {nm})\)的了

代码就放我写的那种做法了

#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef __int128 i128;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=305,INF=1e9;
int n,m,p,a[N][N],f[N][N]; vector <pi> pos[N*N];
#define lowbit(x) (x&-x)
class Tree_Array1
{
	private:
		int lim,mi[N];
	public:
		inline void init(void)
		{
			for (RI i=0;i<=m;++i) mi[i]=INF;
		}
		inline void add(RI x,CI y)
		{
			for (;x<=m;x+=lowbit(x)) mi[x]=min(mi[x],y);
		}
		inline void reset(RI x)
		{
			for (;x<=m;x+=lowbit(x)) mi[x]=INF;
		}
		inline int get(RI x,int ret=INF)
		{
			for (;x;x-=lowbit(x)) ret=min(ret,mi[x]); return ret;
		}
}A[N],B[N];
class Tree_Array2
{
	private:
		int mi[N];
	public:
		inline void init(void)
		{
			for (RI i=0;i<=m;++i) mi[i]=INF;
		}
		inline void add(RI x,CI y)
		{
			for (;x;x-=lowbit(x)) mi[x]=min(mi[x],y);
		}
		inline void reset(RI x)
		{
			for (;x;x-=lowbit(x)) mi[x]=INF;
		}
		inline int get(RI x,int ret=INF)
		{
			for (;x<=m;x+=lowbit(x)) ret=min(ret,mi[x]); return ret;
		}
}C[N],D[N];
#undef lowbit
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	RI i,j; for (scanf("%d%d%d",&n,&m,&p),i=1;i<=n;++i)
	for (j=1;j<=m;++j) scanf("%d",&a[i][j]),pos[a[i][j]].push_back(pi(i,j));
	for (i=1;i<=n;++i) A[i].init(),B[i].init(),C[i].init(),D[i].init();
	for (pos[0].push_back(pi(1,1)),i=1;i<=p;++i)
	{
		for (auto [x,y]:pos[i-1])
		A[x].add(y,-x-y+f[x][y]),B[x].add(y,x-y+f[x][y]),C[x].add(y,y-x+f[x][y]),D[x].add(y,x+y+f[x][y]);
		for (auto [x,y]:pos[i])
		{
			f[x][y]=INF; for (j=1;j<=x;++j)	f[x][y]=min(f[x][y],min(x+y+A[j].get(y),x-y+C[j].get(y)));
			for (j=x;j<=n;++j) f[x][y]=min(f[x][y],min(y-x+B[j].get(y),-x-y+D[j].get(y+1)));
		}
		for (auto [x,y]:pos[i-1])
		A[x].reset(y),B[x].reset(y),C[x].reset(y),D[x].reset(y);
	}
	auto [x,y]=pos[p][0]; printf("%d",f[x][y]);
	return 0;
}

标签:Vanya,typedef,nm,int,Treasure,CF677D,long,include,define
From: https://www.cnblogs.com/cjjsb/p/17707119.html

相关文章

  • Vanya and Brackets 题解
    题目传送门一道枚举题。枚举左括号和右括号的位置括号,为了答案最优,左括号只能在开头或者*的右边。右括号只能在末尾或者*的左边。每一次枚举都计算一下这个加了括号后表达式的值,最后取最大值即可。Code#include<bits/stdc++.h>#definelllonglong#defineINF1e9usi......
  • 4.[1201D - Treasure Hunting](https://codeforces.com/problemset/problem/1201/D)
    4.1201D-TreasureHunting题目意思:在一个n*m的地图上面,左下角的坐标是(1,1),最开始你位于左下角,一秒钟你可以进行往左或者往右的操作,你只能在一些特殊的列上面进行往上移动的操作,你不可以往下移动。现在告诉你k个宝藏的坐标信息以及哪些列是允许往上的,问最后至少要几秒可以遍历k......
  • Codeforces Round #308 (Div. 2) E. Vanya and Brackets
    Vanyaisdoinghismathshomework.Hehasanexpressionofform,wherex1, x2, …, xnaredigitsfrom1to9,andsignrepresentseitheraplus‘+’orthemultiplicationsign‘*’.Vanyaneedstoaddonepairofbracketsinthisexpressionsothattoma......
  • hdu 5446 长春区域赛网络赛1010 Unknown Treasure(lucas定理+中国剩余定理+移位乘法)
    题目链接:hdu5446题目大意:求出Cmn%M,M=p1⋅p2⋯pk题目分析:首先对于每个质数pi我们,我们可以利用Lucas定理求出Cmn%pi的值,Lucas定理如下:Cmn%p=Cm/pn/p⋅Cm%pn%p%p然后我们可以利用中国剩余定理求取最后答案:M=∏i=1kpi,Mi=M/piCmn%M=∑i=1kCmn%pi⋅Mi⋅inv[Mi]因为做乘法......
  • Codeforces Round #286 (Div. 2) C题 Mr. Kitayuta, the Treasure Hunter (DFS+记忆化D
    题目地址:http://codeforces.com/contest/505/problem/C从d点开始,每个点都有三个方向,形成了一棵树,那么就从跟结点开始进行dfs查找,dp数组记录当前的点和长度,当这两个条件相同的时候,显然,后面的子树是完全相同的,于是用记忆化来优化。代码如下:#include<iostream>#include<string.h>#......
  • CF1787I Treasure Hunt 题解
    题目链接题意描述:定义一个序列的权值为一段前缀与一段子段,满足要么前缀与子段不交,要么完全包含的和的最大值,给定一个序列\(a\),求\(a\)的所有子区间的权值和\(n\le1......
  • 题解 [ABC227F] Treasure Hunting
    简单DP,当时赛时没做出来,怎么回事呢。在DP过程中并不好维护前\(k\)大都是什么,没有办法把它放到状态里,因此我们枚举第\(k\)大数的下标\(a_{x,y}\)。然后就好办了,设......
  • HDU 3468 Treasure Hunting
    DescriptionDoyouliketreasurehunting?Today,withoneofhisfriend,iSeaisonaventuretripagain.Asmostmoviesaid,theyfindsomanygoldhid......
  • HDU 5446 Unknown Treasure
    ProblemDescriptionOnthewaytothenextsecrettreasurehidingplace,themathematiciandiscoveredacaveunknowntothemap.Themathematicianenter......
  • CF C. Mr. Kitayuta, the Treasure Hunter
    题目链接https://codeforces.com/problemset/problem/505/C题目描述首先这样的题目可以想到搜索和普通线性dp但是搜索的话时间复杂度到了1e12了(应该没错)而正常dp[......