zoukankan      html  css  js  c++  java
  • 【LOJ #3193】「ROI 2019 Day2」机器人高尔夫球赛(DP+Map)

    传送门

    如果不考虑坐标范围可以显然的得到一个O(nm)O(nm)dpdp

    实际上可以发现对于一个位置,
    如果一个洞不是和他的曼哈顿距离小于等于2,那么就一定不会被这个洞更新

    并且除此之外就只可能会被左下方的点更新

    因此只需要把所有特殊更新的点提出来
    按对角线用MapMap维护转移即可

    #include<bits/stdc++.h>
    using namespace std;
    #define cs const
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define ll long long
    #define pb push_back
    #define bg begin
    cs int RLEN=1<<20|1;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ib==ob)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
    	char ch=gc();
    	int res=0;bool f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
    template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
    cs int mod=998244353;
    inline int add(int a,int b){return (a+=b)>=mod?(a-mod):a;}
    inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
    inline int mul(int a,int b){static ll r;r=1ll*a*b;return (r>=mod)?(r%mod):r;}
    inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
    inline void Dec(int &a,int b){a-=b,a+=a>>31&mod;}
    inline void Mul(int &a,int b){static ll r;r=1ll*a*b,a=(r>=mod)?(r%mod):r;}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
    inline int Inv(int x){return ksm(x,mod-2);}
    inline int fix(int x){return (x<0)?(x+mod):x;}
    cs int N=100005;
    map<pii,int>val;
    map<int,int>f;
    map<int,int>pos;
    int n,m,k,tot,ans,buc[N<<3];
    pii p[N<<3];
    #define It map<int,int>::iterator
    struct comp{
    	inline bool operator ()(cs pii &a,cs pii &b){
    		return (a.fi+a.se==b.fi+b.se)?(a.fi<b.fi):(a.fi+a.se>b.fi+b.se);
    	}
    };
    inline int calc(int x,int y){
    	if(val.count(pii(x,y)))return val[pii(x,y)];
    	int v1=0,v2=0;
    	if(val.count(pii(x+1,y)))v1=val[pii(x+1,y)];
    	else v1=max(f[x-y],f[x-y+2]);
    	if(val.count(pii(x,y+1)))v2=val[pii(x,y+1)];
    	else v2=max(f[x-y],f[x-y-2]);
    	return min(v1,v2);
    }
    int main(){
    #ifdef Stargazer
    freopen("lx.in","r",stdin);
    #endif
    	n=read(),m=read(),k=read();
    	for(int i=1;i<=k;i++){
    		int x=read(),y=read(),v=read();
    		val[pii(x,y)]=v;
    		for(int k=0;k<=2&&x-k>0;k++)
    		for(int j=0;k+j<=2&&y-j>0;j++)
    		p[++tot]=pii(x-k,y-j);
    	}
    	sort(p+1,p+tot+1,comp());
    	tot=unique(p+1,p+tot+1)-p-1;
    	for(int i=1,nxt;i<=tot;i=nxt+1){
    		for(nxt=i;nxt<tot&&p[nxt].fi+p[nxt].se==p[nxt+1].fi+p[nxt+1].se;nxt++);
    		for(int j=i;j<=nxt;j++){
    			int x=p[j].fi,y=p[j].se;
    			if(f.count(x-y))Add(ans,fix(1ll*f[x-y]*(p[pos[x-y]].fi-x)%mod));
    			buc[j]=calc(x,y);
    		}
    		for(int j=i;j<=nxt;j++){
    			int x=p[j].fi,y=p[j].se;
    			f[x-y]=buc[j],pos[x-y]=j;
    		}
    	}
    	for(It it=f.bg();it!=f.end();it++){
    		Add(ans,fix(1ll*it->se*min(p[pos[it->fi]].fi,p[pos[it->fi]].se)%mod));
    	}
    	cout<<ans<<'
    ';
    }
    
  • 相关阅读:
    [引]Windows Server 2003 : 服务器群集
    周国平:(爱情)永远未完成
    企业管理常用缩写术语之中英文对照表(含解释)
    微软相关中文网站
    陈安之:NAC神经链调正术
    学会不要再争吵
    Oracle基础学习四:字符串 数字 日期 等 相关函数
    贪多嚼不烂
    frameset 框架传值点滴
    陈安之成功的十个关键
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328342.html
Copyright © 2011-2022 走看看