LuoguP5897 [IOI2013]wombats
LuoguP5897 [IOI2013]wombats
题目描述
Solution
记f[i][j]f[i][j]f[i][j]表示从(0,i)(0,i)(0,i)到(0,j)(0,j)(0,j)的最短路,可以通过一行一行DPDPDP在O(R∗C2)O(R*C^2)O(R∗C2)的时间内求得,而每次修改需要重新求答案,所以时间复杂度为O(R∗C2∗Q)O(R*C^2*Q)O(R∗C2∗Q)。
但我们发现这题的RRR很大,而CCC很小,所以我们考虑把RRR这一位扔到线段树上,线段树的一个区间记录了一个C∗CC*CC∗C的矩阵。线段[l,r][l,r][l,r]中矩阵的一个点Di,jD_{i,j}Di,j记录从(l,i)(l,i)(l,i)到(r,j)(r,j)(r,j)的距离,这样每次修改就只需要修改lognlog^nlogn。
接下来考虑两个线段怎么合并,如果暴力枚举的话时间复杂度为O(n3)O(n^3)O(n3)(类似floydfloydfloyd的方法,枚举i,ji,ji,j和中间点kkk),但我们发现这里有决策单调性,我们固定一个点iii,枚举jjj,假设jjj的最优决策点为kkk,那么对于任意的j′>jj'>jj′>j,j′j'j′的最优决策点k′>kk'>kk′>k,这样就可以通过分治做到O(n2lgn)O(n^2lgn)O(n2lgn)或直接记录决策点位置做到O(n2)O(n^2)O(n2)。
这样优化之后时间复杂度就OKOKOK了。然而空间还是太大了,于是有一个神奇的套路:在线段树中,若线段的长度小于一个阈值ttt,则通过之前说的O(n3)O(n^3)O(n3)暴力求解DDD矩阵。
我的程序当阈值设为20的时候能过。
所以时空复杂度就是O(能过)O(能过)O(能过)了(懒得算QAQ)
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=5005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f;
}
int n,m,d1[MAXN][205],d2[MAXN][205],s[MAXN][205],tmp[205][205];
struct Matrix
{int A[205][205],l,r;void clear(int L,int R) {l=L,r=R;for (int i=1;i<=m;i++) for (int j=1;j<=m;j++) A[i][j]=INF;}Matrix(int L=0,int R=0) { clear(L,R); }void rebuild(int L,int R){l=L,r=R;for (int i=1;i<=m;i++) for (int j=1;j<=m;j++) A[i][j]=abs(s[l][i]-s[l][j]);for (int k=l+1;k<=r;k++){for (int i=1;i<=m;i++)for (int j=1;j<=m;j++) A[i][j]+=d2[k][j],tmp[i][j]=A[i][j];for (int i=1,smin;i<=m;i++){smin=tmp[i][1];for (int j=2;j<=m;j++) smin+=d1[k][j],upmin(smin,tmp[i][j]),upmin(A[i][j],smin);smin=tmp[i][m];for (int j=m-1;j>=1;j--) smin+=d1[k][j+1],upmin(smin,tmp[i][j]),upmin(A[i][j],smin);}}}void print(){cout<<l<<" "<<r<<endl;for (int i=1;i<=m;i++){for (int j=1;j<=m;j++) cout<<A[i][j]<<" ";cout<<endl;}cout<<endl;}
} ans;
struct Segment_Tree
{Matrix tree[1005];void Solve(Matrix &x,Matrix &y,int t,int l,int r,int L,int R){ int mid=(l+r)>>1,k=L;for (int i=L+1;i<=R;i++)if (x.A[t][i]+d2[y.l][i]+y.A[i][mid]<x.A[t][k]+d2[y.l][k]+y.A[k][mid]) k=i;ans.A[t][mid]=x.A[t][k]+d2[y.l][k]+y.A[k][mid];if (l==r) return;Solve(x,y,t,l,mid,L,k);Solve(x,y,t,mid+1,r,k,R);}Matrix Merge(Matrix &x,Matrix &y){ ans.clear(x.l,y.r);for (int i=1;i<=m;i++) Solve(x,y,i,1,m,1,m);return ans;}void up(int x) { tree[x]=Merge(tree[x<<1],tree[x<<1|1]); }void build(int x,int l,int r){if (r-l<=20) { tree[x].rebuild(l,r); return; }int mid=(l+r)>>1;build(x<<1,l,mid);build(x<<1|1,mid+1,r);up(x);}void change(int x,int l,int r,int y){if (r-l<=20) { tree[x].rebuild(l,r); return; }int mid=(l+r)>>1;if (y<=mid) change(x<<1,l,mid,y);else change(x<<1|1,mid+1,r,y);up(x);}
} segment;int main()
{n=read(),m=read();for (int i=1;i<=n;i++)for (int j=2;j<=m;j++) d1[i][j]=read(),s[i][j]=s[i][j-1]+d1[i][j];for (int i=2;i<=n;i++)for (int j=1;j<=m;j++) d2[i][j]=read();segment.build(1,1,n);int Case=read();while (Case--){int opt=read();if (opt==1) { int x=read()+1,y=read()+2;d1[x][y]=read(); for (;y<=m;y++) s[x][y]=s[x][y-1]+d1[x][y];segment.change(1,1,n,x);}else if (opt==2) {int x=read()+2,y=read()+1;d2[x][y]=read(),segment.change(1,1,n,x);}else printf("%d\n",segment.tree[1].A[read()+1][read()+1]);}return 0;
}
LuoguP5897 [IOI2013]wombats相关推荐
- [IOI2013]wombats(网格图分治+线段树+决策单调性)
洛谷题目传送门 老话说的好,看见网格图,就想分治 我们对行进行分治 设当前分支节点是k,区间是 l [ k ] l[k] l[k]行到 r [ k ] r[k] r[k]行,他的分治子节点分别是 l ...
- node和npm是什么_什么是npm? 面向初学者的Node Package Manager教程
node和npm是什么 This article should serve as an all-in-one essential guide for Node.js' favorite sidekic ...
- 全国计算机大赛获奖奖品,国内含金量高的竞赛证书全汇总
国内含金量高的竞赛证书全汇总 来源:石家庄新闻网 2017-11-17 14:28:50 国内多数地区小升初.初升高及高校自主招生中认可的竞赛证书汇总如下: 一.语文学科及作文竞赛 1.奥林匹克杯全国 ...
- 2019.4.summary
2019.4.1 BZOJ1061: [Noi2008]志愿者招募 真心有点难QAQ https://www.byvoid.com/zhs/blog/noi-2008-employee 看void爷的 ...
- bluej 编程_BlueJ和Greenfoot:学习Java的最佳IDE
bluej 编程 您说您想学习Java. 它可能是一种令人生畏的语言. 如果您是一名新程序员,这甚至似乎是不可渗透的. 但是,您深吸一口气,决心下定决心. 好的,首先要做的是:您需要已经阅读过的那些集 ...
- 清华大学 计算机科学理论,高一被清华姚班录取,一个网瘾少年到理论计算机科学家的蜕变...
当陈立杰站在清华大学特奖答辩的讲台上时,无数目光注视着他.前方是理论计算机科学家的坦途,而过去则是重度网瘾少年的曾经.他在旁人看来不可及的人生,只是一个普通人不普通的蜕变. 网瘾少年 从小学开始,陈立 ...
- 前端之样式化链接、web字体
前端之样式化链接 链接 链接状态 默认样式 应用样式 在链接后插入外部链接图标 将链接样式化为按钮 Web字体 查找字体 免费的字体经销商 在线字体服务 Web 字体 使用下载字体(第一次用) 我下载 ...
- 《Python自然语言处理-雅兰·萨纳卡(Jalaj Thanaki)》学习笔记:04 预处理
03 预处理 4.1 处理原始语料库文本 4.1.1 获取原始文本 4.1.2 小写化转换 4.1.3 分句 4.1.4 原始文本词干提取 4.1.5 原始文本词形还原 4.1.6 停用词去除 4.2 ...
- 【CSS】样式化文字
根据MDN网站学习记录笔记 样式化文字 基本文本和字体样式 字体种类 字体样式.字体粗细 文本转换.文本装饰 文字阴影 文本布局 样式列表 符号样式 项目符号位置 自定义项目符号图片 管理列表计数 样 ...
最新文章
- [c#基础]ICloneable接口
- Netty Pipeline源码分析(2)
- jps could not synchronize with target
- 大数据实战之环境搭建(七)
- 仿windows造字程序的 ASP.NET图片组合生成控件
- opencv cv2.LUT()(使用查找表中的值填充输出数组)
- ​电赛 | 19年全国一等奖,北航学子回忆录(上)
- android studio 分页,Android Paging codelab
- docker 容器命令
- 003.linux开发环境配置及linux极速入门
- 【动态规划】状压dp:蓝桥2020补给(旅行商问题)
- 故事的小黄花,从CSDN那年就飘着
- 水晶报表-推拉模式实例
- 根据输入时间判断年龄是否在18~68周岁之间
- 技术分析淘宝的超卖宝贝
- 打卡1 谭浩强c语言程序设计第三章
- web前端开发实训报告,HTML表单标签
- CSS背景颜色之奇技淫巧
- 淦!为什么到处都是广告!
- linux dd 克隆很慢,使用dd命令进行SD卡克隆
热门文章
- 难以摸透的直男脑回路......
- 酒桌上,领导将酒泼到你脸上......
- Python到底是有什么魅力,让程序猿为它折腰?
- 一堂儿童科学实验课引起的思考:数学和化学有什么关系?
- 我敢打赌,这世界没有python数据分析解决不了的问题
- php返回一个变量,PHP从另一个文件获取变量
- java对象头_我的并发编程(二):java对象头以及synchronized升级过程
- 我丢,去面试初级Java开发岗位,被问到泛型?
- oracle体系结构和组件图示,Oracle 体系结构组件
- 公众号滑动图代码_实用技巧:公众号封面图如何提取?