题目

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. 【转载】IOS之禁用UIWebView的默认交互行为

    原文地址 :IOS之禁用UIWebView的默认交互行为 http://my.oschina.net/hmj/blog/111344 UIKit提供UIWebView组件,允许开发者在App中嵌入We ...

  2. POJ 1921 Paper Cut(计算几何の折纸问题)

    Description Still remember those games we played in our childhood? Folding and cutting paper must be ...

  3. js随机数算法

    function rnd( seed ){ seed = ( seed * 9301 + 49297 ) % 233280; //为何使用这三个数? return seed / ( 233280.0 ...

  4. 声明变量&定义变量

            从编译原理上来说,声明是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存.而定义就是分配了内存.这对于以关键字extern进行声明是一定成立的,而对声明格式“ ...

  5. C语言--链表基础模板

    1.建立结构体 struct ST { int num;///学号 int score;///成绩 struct ST*next; };///结构体 2.空链表的创建 struct ST creatN ...

  6. Bus of Characters(栈和队列)

    In the Bus of Characters there are nn rows of seat, each having 22 seats. The width of both seats in ...

  7. hashMap原理(java8)

    (1) HashMap:它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的. HashMap最多只允许一条记录的键为null,允许多 ...

  8. python学习第二天-基本数据类型常用方法

    1.直入主题 python中基本的数据类型有 数字(整形,长整形,浮点型,复数) 字符串 字节串:在介绍字符编码时介绍字节bytes类型 列表 元组 字典 集合 下面我们直接将以下面几个点进行学习 # ...

  9. 【OpenGL】无法启动此程序,因为计算机中丢失 glut32.dll。尝试重新安装该程序以解决此问题。

    运行OpenGL程序的时候报错,如图: 解决方法:把glut32.dll复制到C:\Windows\SysWOW64目录下,而不是像网上教程那样复制到C:\Windows\System32目录下. 原 ...

  10. java.lang.ClassNotFoundException: com.google.gson.Gson 问题解决

    我是这么解决:把gson.jar放到WEB-INF/lib目录下. 放在其他目录就会报错.