题目

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. Qt-QML-ComboBox-自定义,实现状态表示,内容可以动态正价,使用ListModel

    哎呀呀呀, 问:杀死一个程序员一个程序要需要进步? 答:改三次需求 我感觉我就要再这需求的变更中被杀死了.不管怎么说,总是要跟着需求走的的,客户才是第一么(要不是因为钱,我才不会了) 下面先上个效果 ...

  2. Linux命令应用大词典-第39章 网络安全

    39.1 rtacct:网络统计工具 39.2 nmap:报告远程主机特征 39.3 tcpdump:实现网络数据采集分析 39.4 iptstate:显示IP表状态表条目 39.5 nstat:监控 ...

  3. Java开发工程师(Web方向) - 04.Spring框架 - 第5章.Web框架

    第5章--Web框架 Web框架概述 Web框架单元测验 本次得分为:13.50/15.00, 本次测试的提交时间为:2017-09-25 1单选(2分) 关于Spring MVC中Dispatche ...

  4. 《Effective C++》读书笔记 被你忽略的关于构造析构赋值

    如果程序员没有定义,那么编译器会默认隐式为你创建一个copy构造函数,一个copy赋值操作符,一个析构函数.另外如果你没有声明任何构造函数,编译器会为你声明一个default构造函数. 但是只有当这些 ...

  5. Python入门(5)

    导览: 函数 集合 迭代器与生成器 模块 一.函数 只要学过其他编程语言应该对函数不太陌生,函数在面向过程的编程语言中占据了极重要的地位,可以说没有函数,就没有面向过程编程,而在面向对象语言中,对象的 ...

  6. BZOJ 3166 HEOI2013 ALO 可持久化trie+st表

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3166(洛谷上也有) 题意概述: 给出一个序列,对于一个区间,其权值为区间中的次大值亦或区 ...

  7. POJ 3028 Shoot-out(概率DP)

    Description This is back in the Wild West where everybody is fighting everybody. In particular, ther ...

  8. HDU 4169 Wealthy Family(树形DP)

    Problem Description While studying the history of royal families, you want to know how wealthy each ...

  9. Repair the Wall (贪心)

    Long time ago , Kitty lived in a small village. The air was fresh and the scenery was very beautiful ...

  10. Java中的线程的优先级

    Java 中线程优先级简介: 1. Java 提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程. 按照线程的优先级决定应该调度哪个线程来执行. 2. 线程的优先级用数字表示, 范围从 1 到 ...