题目

W神爷的题解

高级数据结构

T1:

其实是一道easy题,$O(n^3log n)$ 也是能卡过去的,本着要的70分的心态,最后尽然A了。

如果是正解则是$O(n^3)$,当确定你要选择的列时,不断往下扩展,因为此刻是单调函数,所以可以用单调队列优化。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int f=,ans=;char c;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ans=ans*+c-'';c=getchar();}
return f*ans;
}
int n,a[][],s[][],hs[][],k,maxn;
bool check(int x1,int y1,int x2,int y2){return hs[x2][y2]-hs[x2][y1-]-hs[x1-][y2]+hs[x1-][y1-]<=k;}
int main()
{
n=read(),k=read();
for(int i=;i<=n;i++){
for(int j=;j<=n;j++) a[i][j]=read(),s[i][j]=s[i][j-]+a[i][j];
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++) hs[i][j]=hs[i-][j]+s[i][j];
}
for(int y1=;y1<=n;y1++){
for(int y2=y1;y2<=n;y2++){
int l=;
for(int r=;r<=n;r++){
while(!check(l,y1,r,y2)) l++;
maxn=max(maxn,(r-l+)*(y2-y1+));
}
}
}
printf("%d\n",maxn);
return ;
}

O(n^3)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int f=,ans=;char c;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ans=ans*+c-'';c=getchar();}
return f*ans;
}
int n,a[][],s[][],hs[][],k,maxn;
bool check(int x1,int y1,int x2,int y2){
int s1=,s2=,s3=;
s1=s[x1][y2]-s[x1][y1-];
if(x1!=x2)s2=s[x2][y2]-s[x2][y1-];
if(x2>x1+) s3=(hs[x2-][y2]-hs[x1][y2])-(hs[x2-][y1-]-hs[x1][y1-]);
if(s1+s2+s3>k) return ;
return ;
}
int towfen(int x1,int y1,int x2,int ll,int rr){
int l=ll,r=rr,mid,maxn=;
while(l<=r){
mid=l+r>>;
if(check(x1,y1,x2,mid)) maxn=max(maxn,mid),l=mid+;
else r=mid-;
}return maxn;
}
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
n=read(),k=read();
if(n*n<=k){
cout<<n*n;
return ;
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++) a[i][j]=read(),s[i][j]=s[i][j-]+a[i][j];
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++) hs[i][j]=hs[i-][j]+s[i][j];
}
for(int x1=;x1<=n;x1++)
{
for(int y1=;y1<=n;y1++)
{
for(int x2=n;x2>=x1;x2--)
{
if((n-y1+)*(x2-x1+)<=maxn) break;
int y2=towfen(x1,y1,x2,y1,n);
maxn=max(maxn,(x2-x1+)*(y2-y1+));
}
}
}
printf("%d",maxn);
return ;
}
/*
5 4
1 0 1 0 1
0 1 0 0 0
1 0 1 0 0
1 1 1 1 1
0 0 1 0 1
*/

O(n^3logn)

T2:

考试时的想法:看到题,发现与YBT的一本通上的一道题十分类似(this),所以就一直在想最小生成树,就再打,打了半天,发现这个方法正确性不显然,打完了,与自己的暴力程序对拍,WAWAWA,全是WA,心态炸了,最后交了个暴力程序,其实树形dp也是想过,但没有想过这么强大的后效性怎么处理掉,所以就放弃了。

$30points$:暴力

$extra 40 points$:

dp方程,设$dp(i)$表示前$i$ 个城市的代价均已计算,且最后一个机场设在了第$i$个城市的最小花费,所以就可以瞎搞了?为什么这样无后效性呢,是因为$dp$方程设计时是算出前面的,为什么与后面的无影响呢,因为可以传参

$100 points$:

树形$dp$.一个现在很明显的东西,所以要设计一个无后效性,快速的方程,然后其实就跟上面的一样了,详情看W神爷的题解

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read()
{
int f=,ans=;char c;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ans=ans*+c-'';c=getchar();}
return f*ans;
}
struct node{
int u,v,w,nex;
}x[];
int g[],cnt,dis[][],n,cost[],head[],dp[][];
void add(int u,int v,int w){
x[cnt].u=u,x[cnt].v=v,x[cnt].nex=head[u],x[cnt].w=w,head[u]=cnt++;
}
void dfs(int f,int fa,int w,int root){
dis[root][f]=w;
for(int i=head[f];i!=-;i=x[i].nex){
if(x[i].v==fa) continue;
dfs(x[i].v,f,w+x[i].w,root);
}
}
void dp_tree(int f,int fa){
for(int i=head[f];i!=-;i=x[i].nex){
if(x[i].v==fa) continue;
dp_tree(x[i].v,f);
}
for(int i=;i<=n;i++){
dp[f][i]=cost[i]+dis[f][i];
for(int j=head[f];j!=-;j=x[j].nex){
if(x[j].v==fa) continue;
dp[f][i]+=min(g[x[j].v],dp[x[j].v][i]-cost[i]);
}
}
for(int i=;i<=n;i++) g[f]=min(g[f],dp[f][i]);
return;
}
int main()
{
// freopen("design.in","r",stdin);
// freopen("design.out","w",stdout);
memset(head,-,sizeof(head));
memset(g,/,sizeof(g));
n=read();
for(int i=;i<=n;i++) cost[i]=read();
for(int i=;i<n;i++){int u=read(),v=read(),w=read();add(u,v,w),add(v,u,w);}
for(int i=;i<=n;i++) dfs(i,,,i);
dp_tree(,);
cout<<g[];
}
/*
6
2 1 2 4 2 3
1 2 4
1 3 4
2 6 2
2 4 100
4 5 2
*/

T3:

线段树优化建图,以前不知道的东西,其实也是一个比较好想的方法,就是建一棵以$n$作为长度的线段树,用$dfs$的时间戳进行编号,方便建图。先将父亲节点向两个儿子连一条长度为$0$的边,然后再每个点向线段树中所对应的点连一条边权为$0$的边。因为每个点有一个移动距离所以可以二分求出它可以到达的左右端点,然后再跑$dijkstra$即可($spfa$,它死了)。为什么这样写是对的呢,为什么要建边权$0$边呢,是因为要保持可连通关系,就像能量流动一样,必须有层传导关系,给下面进行贡献,为什么不向上连边,是因为上面包含的区间比下面的长,就这么简单。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
inline long long read()
{
long long f=,ans=;char c;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ans=ans*+c-'';c=getchar();}
return f*ans;
}
struct node{
long long u,v,w,nex;
}x[];
long long head[],dis[],vis[],pos[],w[],t[],n,ll[],rr[],cnt,s1,s2;
void add(long long u,long long v,long long w){
x[cnt].u=u,x[cnt].v=v,x[cnt].w=w,x[cnt].nex=head[u],head[u]=cnt++;
}
long long query_l(long long dis,long long p){
long long l=,r=n,mid,minn=<<-,pp=dis-p;
while(l<=r){
mid=l+r>>;
if(pp<=pos[mid]) minn=min(minn,mid),r=mid-;
else l=mid+;
}
return minn;
}
long long query_r(long long dis,long long p){
long long l=,r=n,maxn=,mid,pp=dis+p;
while(l<=r){
mid=l+r>>;
if(pp>=pos[mid]) maxn=max(maxn,mid),l=mid+;
else r=mid-;
}
return maxn;
}
void build(long long k,long long l,long long r){
if(l==r){add(k+n,l,);return;}
long long mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
add(k+n,(k<<)+n,),add(k+n,(k<<|)+n,);
return;
}
void query(long long k,long long l,long long r,long long x,long long y,long long w,long long st){
if(x<=l&&r<=y){add(st,k+n,w);return;}
long long mid=l+r>>;
if(x<=mid) query(k<<,l,mid,x,y,w,st);
if(mid<y) query(k<<|,mid+,r,x,y,w,st);
return;
}
void dijkstra(){
memset(dis,,sizeof(dis));
priority_queue<pair<long long,long long> > que;
dis[s1]=;
que.push(make_pair(,s1));
while(!que.empty()){
long long xx=que.top().second;que.pop();
if(vis[xx]) continue;
vis[xx]=;
for(long long i=head[xx];i!=-;i=x[i].nex){
if(dis[x[i].v]>dis[xx]+x[i].w){
dis[x[i].v]=dis[xx]+x[i].w;
que.push(make_pair(-dis[x[i].v],x[i].v));
}
}
}
return;
}
int main()
{
memset(head,-,sizeof(head));
n=read(),s1=read(),s2=read();
for(long long i=;i<=n;i++) pos[i]=read();
for(long long i=;i<=n;i++) w[i]=read();
for(long long i=;i<=n;i++) t[i]=read();
for(long long i=;i<=n;i++) ll[i]=query_l(pos[i],w[i]),rr[i]=query_r(pos[i],w[i]);
build(,,n);
for(long long i=;i<=n;i++) query(,,n,ll[i],rr[i],t[i],i);
dijkstra();
cout<<dis[s2];
}

分数:$100+30+60=190$

20181022 考试记录&高级数据结构的更多相关文章

  1. GO语言的进阶之路-Golang高级数据结构定义

    GO语言的进阶之路-Golang高级数据结构定义 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们之前学习过Golang的基本数据类型,字符串和byte,以及rune也有所了解, ...

  2. Python中的高级数据结构

    数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数据结构,分别是List.Tuple.Dictionar ...

  3. Python中的高级数据结构详解

    这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考 ...

  4. Python中的高级数据结构(转)

    add by zhj: Python中的高级数据结构 数据结构 数据结构的概念很好理解,就是用来将数据组织在一起的结构.换句话说,数据结构是用来存储一系列关联数据的东西.在Python中有四种内建的数 ...

  5. 数据结构(5) 第五天 快速排序、归并排序、堆排序、高级数据结构介绍:平衡二叉树、红黑树、B/B+树

    01 上次课程回顾 希尔排序 又叫减少增量排序 increasement = increasement / 3 + 1 02 快速排序思想 思想: 分治法 + 挖坑填数 分治法: 大问题分解成各个小问 ...

  6. 高级数据结构之 BloomFilter

    高级数据结构之 BloomFilter 布隆过滤器 https://en.wikipedia.org/wiki/Bloom_filter A Bloom filter is a space-effic ...

  7. JS高级-数据结构的封装

    最近在看了<数据结构与算法JavaScript描述>这本书,对大学里学的数据结构做了一次复习(其实差不多忘干净了,哈哈).如果能将这些知识捡起来,融入到实际工作当中,估计编码水平将是一次质 ...

  8. 数据结构与算法——常用高级数据结构及其Java实现

    前文 数据结构与算法--常用数据结构及其Java实现 总结了基本的数据结构,类似的,本文准备总结一下一些常见的高级的数据结构及其常见算法和对应的Java实现以及应用场景,务求理论与实践一步到位. 跳跃 ...

  9. [总结] NOIP 前的考试记录

    sb博主又犯sb错误了! 他觉得以往模拟赛因为犯sb错误扔的分足足有1k分了! 于是他想记录一下自己犯的sb错误看看自己到底有多sb! 嗯就从今天开始吧 2018.9.28 1. 二分边界写错.骚什么 ...

随机推荐

  1. hdu1181变形课(floyd)

    变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submis ...

  2. 【label】标签组件说明

    label标签组件 用来改进表单组件的可用性,使用for属性找到对应的id,或者将控件放在该标签下,当点击时,就会触发对应的控件.目前可以绑定的控件有:<button/>, <che ...

  3. Java学习 · 初识 面向对象深入一

    面向对象深入 1.面向对象三大特征 a) 继承 inheritance 子类可以从父类继承属性和方法 子类可以提供自己的属性方法 b) 封装 encapsulation 对外隐藏某些属性和方法 对外公 ...

  4. Android开发-API指南-<permission-tree>

    <permission-tree> 英文原文:http://developer.android.com/guide/topics/manifest/permission-tree-elem ...

  5. kvm虚拟化操作

    本节演示如何使用 virt-manager 启动 KVM 虚机. 首先通过命令 virt-manager 启动图形界面 # virt-manager 点上面的图标创建虚机 给虚机命名为 kvm1,这里 ...

  6. Twaver的mono-desiner导出的json文件解析

    以画的交换机为例,其他大概都差不多. 利用Twaver做出交换机模型如图1所示,其中,每一个端口都是一个单独的对象.具体Twaver操作流程参见网址:http://twaver.servasoft.c ...

  7. 在linux下PHP和Mysql环境搞事情

    研发部门同事开发了一个接口管理辅助工具Shepherd,要求搭建在内网环境中,遇到点小问题记一下. 将开发的文件上传只web目录下,更改数据库ip,可以正常打开 登陆用户信息,此时需要连接数据库来验证 ...

  8. Python为什么会打印两个\

    在Python里面,如果\后面不是一个合法的转移字符,那么,Python会打印两个\,换句话说,Python将\也当成普通字符看待,而不是转义符的标志: >>>S = 'C:\py\ ...

  9. LintCode-365.二进制中有多少个1

    二进制中有多少个1 计算在一个 32 位的整数的二进制表式中有多少个 1. 样例 给定 32 (100000),返回 1 给定 5 (101),返回 2 给定 1023 (111111111),返回 ...

  10. Python 零碎信息-基础 02

    1. range xrange 的差别 1.1 range 返回列表对象. 1.2 xrange 返回xrange对象  不需要返回列表里面的值, 节省内存. >>> range(1 ...