2018.10.22图图的游戏 / 图图的设计 / 图图的旅行

Posted scx2015noip-as-php

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018.10.22图图的游戏 / 图图的设计 / 图图的旅行相关的知识,希望对你有一定的参考价值。

题目

我是一个小沙比,爆零本领强~

T1

看起来是一道很捞的、做过无数遍的区间最大值。

直接$O(n^3)$做一做就完了……

具体做法就是预处理每行的前缀和,然后二重循环枚举一个固定的列区间,再用单调队列的思想,从第一行不停向下扩展行区间,如果矩阵内总和$gt k$ 了就从行区间顶部不停删行,删到矩阵内总和$le k$ 为止。每当矩阵总和满足限制时,更新矩阵面积最大值即可。

当然如果你很想大战$T1$的话,可以写个$O(n^2*log(n^2))$的主席树?

技术分享图片
 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define N 501
 8 using namespace std;
 9 inline int read(){
10     int x=0; bool f=1; char c=getchar();
11     for(;!isdigit(c);c=getchar()) if(c==-) f=0;
12     for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^0);
13     if(f) return x;
14     return 0-x;
15 }
16 int n,m,e[N][N],sum[N][N],x,ans;
17 int main(){
18     n=read()+1,m=read();
19     int i,j,k,go;
20     for(i=1;i^n;++i)
21         for(j=1;j^n;++j)
22             sum[i][j]=sum[i][j-1]+read();
23     for(i=1;i^n;++i){
24         for(j=i;j^n;++j){
25             x=0, go=1;
26             for(k=1;k^n;++k){
27                 x+=sum[k][j]-sum[k][i-1];
28                 while(x>m) x-=sum[go][j]-sum[go][i-1], ++go;
29                 ans=max(ans,(j-i+1)*(k-go+1));
30             }
31         }
32     }
33     printf("%d
",ans);        
34     return 0;
35 }
View Code

 

T2

这是一道考验水平的$dp$题(机房最高分$70$

0~30pts:

你写的开心就好

40~50pts:

不知道

60~90pts:

由于是一条链,所以可以考虑链上$dp$,从前往后推。

设$f(i)$为从根到$i$号节点中,让每个点都得到补给所需的总代价的最小值。

易推$f(i)=$min{f(j-1)+$

100pts:

这个dp有点新式……

设$f(i,j)$为以$i$号节点为根的子树中,离点$i$最近的机场设在了节点$j$时,子树中所有点都得到补给所需的总代价的最小值。

然后转移是这样的

 

T3

技术分享图片
  1 #include<bits/stdc++.h>
  2 #define ll long long
  3 #define N 152505
  4 const ll inf=1ll<<62;
  5 using namespace std;
  6 inline int read(){
  7     int x=0; bool f=1; char c=getchar();
  8     for(;!isdigit(c);c=getchar()) if(c==-) f=0;
  9     for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^0);
 10     if(f) return x;
 11     return 0-x;
 12 }
 13 int n,s,t,x[N],y[N],z[N],l[N],r[N];
 14 int root,L,R,u; ll Dis;
 15 struct SegTree{
 16     struct T{
 17         int son[2];
 18         ll dis,tag; //min,max
 19         bool del; 
 20     }tr[N<<3];
 21     int cnt;
 22     inline void pushup(int o){
 23         tr[o].dis = min(tr[tr[o].son[0]].dis, tr[tr[o].son[1]].dis);
 24         //printf("pushup:%lld %lld
",tr[tr[o].son[0]].dis, tr[tr[o].son[1]].dis);
 25     }
 26     inline void pushdel(int o){
 27         tr[o].del = tr[tr[o].son[0]].del & tr[tr[o].son[1]].del;
 28     }
 29     void build(int &o,int l,int r){
 30         o=++cnt;
 31         tr[o].tag=inf, tr[o].del=0;
 32         if(l==r){tr[o].dis=inf; tr[o].son[0]=tr[o].son[1]=0; return;}
 33         int mid=(l+r)>>1;
 34         build(tr[o].son[0],l,mid), build(tr[o].son[1],mid+1,r);
 35         pushup(o);
 36     }
 37     inline void pushdown(int o){
 38         if(tr[o].tag<inf){
 39             int lc=tr[o].son[0], rc=tr[o].son[1];
 40             if(!tr[lc].del) tr[lc].dis=min(tr[lc].dis,tr[o].tag), tr[lc].tag=min(tr[lc].tag,tr[o].tag);
 41             if(!tr[rc].del) tr[rc].dis=min(tr[rc].dis,tr[o].tag), tr[rc].tag=min(tr[rc].tag,tr[o].tag);
 42             tr[o].tag=inf;
 43         }
 44     }
 45     void update(int o,int l,int r){
 46         if(tr[o].del) return;
 47         if(L<=l && r<=R){
 48             tr[o].dis=min(tr[o].dis,Dis), tr[o].tag=min(tr[o].tag,Dis);
 49             return;
 50         }
 51         pushdown(o);
 52         int mid=(l+r)>>1;
 53         if(L<=mid) update(tr[o].son[0],l,mid);
 54         if(R>mid) update(tr[o].son[1],mid+1,r);
 55         pushup(o);
 56     }
 57     void Delete(int o,int l,int r){
 58         if(l==r){tr[o].dis=inf; tr[o].del=1; return;}
 59         pushdown(o);
 60         int mid=(l+r)>>1;
 61         if(u<=mid) Delete(tr[o].son[0],l,mid);
 62         else Delete(tr[o].son[1],mid+1,r);
 63         //printf("Delete:%d %d %lld
",l,r,tr[o].dis);
 64         pushup(o); //printf("Delete:%d %d %lld
",l,r,tr[o].dis);
 65         pushdel(o);
 66     }
 67     void query(int o,int l,int r){ //查询最小值的最小下标 
 68         //printf("query:%d %d %lld
",l,r,tr[o].dis);
 69         if(l==r){u=l, Dis=tr[o].dis; return;}
 70         pushdown(o);
 71         int mid=(l+r)>>1;
 72         //printf("query:%d %d %lld %lld %lld
",l,r,tr[o].dis,tr[tr[o].son[0]].dis,tr[tr[o].son[1]].dis);
 73         if(tr[o].dis==tr[tr[o].son[0]].dis && !tr[tr[o].son[0]].del) query(tr[o].son[0],l,mid);
 74         else if(tr[o].dis==tr[tr[o].son[1]].dis && !tr[tr[o].son[1]].del) query(tr[o].son[1],mid+1,r);
 75     }
 76 }S;
 77 ll ans[N];
 78 void Dij(){
 79     L=R=s, Dis=0;
 80     S.cnt=0;
 81     S.update(root,1,n);
 82     int i;
 83     for(int i=1;i<=n;++i){
 84         S.query(root,1,n);
 85         ans[u]=Dis;
 86         //printf("%d %lld %d %d
",u,ans[u],l[u],r[u]);
 87         if(u==t) break;
 88         Dis+=z[u];
 89         L=l[u],R=r[u];
 90         S.update(root,1,n);
 91         S.Delete(root,1,n);
 92     }
 93 }
 94 int main(){
 95     //freopen("trip9.in","r",stdin);
 96     //freopen("trip.out","w",stdout);
 97     n=read(),s=read(),t=read();
 98     int i;
 99     for(i=1;i<=n;++i) x[i]=read();
100     for(i=1;i<=n;++i) y[i]=read();
101     for(i=1;i<=n;++i) z[i]=read();
102     for(i=1;i<=n;++i){
103         l[i]=lower_bound(x+1,x+n+1,x[i]-y[i])-x,
104         r[i]=upper_bound(x+1,x+n+1,x[i]+y[i])-x-1;
105         //cout<<i<<‘ ‘<<x[i]<<‘ ‘<<y[i]<<‘ ‘<<l[i]<<‘ ‘<<r[i]<<‘
‘;
106     }
107     S.build(root,1,n);
108     Dij();
109     printf("%lld
",ans[t]);
110     return 0;
111 }
112 /*
113 7 3 7
114 -1 0 1 2 3 5 10
115 11 0 1 1 4 10 2
116 3 1 1 1 2 4 5
117 */
View Code

 

以上是关于2018.10.22图图的游戏 / 图图的设计 / 图图的旅行的主要内容,如果未能解决你的问题,请参考以下文章

UOJ #589. 图图的游戏

数据结构—图图的定义图的存储结构

数据结构-图图的常用算法

图图的存储图的遍历

数据结构-图图的定义

条形图图未添加到现有的 tkinter 窗口