ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

noip模拟16

2021-07-16 17:03:44  阅读:189  来源: 互联网

标签:lid ch noip 16 int tr rid id 模拟


cao  这场又挂掉分了,t1求距离打的int直接爆0了。。。。。

T1star way to heaven

怎么说呢,这个题要是看出来了,写个最小生成树的板子就过了,要是看不出来。。。。

我们把这个题目转化一下,说要经过的路径距离星星或边界的距离的最小值最大,

那么我们经过星星与星星或边界的终点肯定是不劣的,那么问题就转化成从左边到右边经过的所有连线的最小距离的1/2最大

我们发现,假设我们把上边界和下边界看作两个点,每个星星都和其他星星以及上下边界有连边,也就是说将他看作一张完全图

从上边界到下边界,有无数条路径,但是只要是从左边到右边经过,那么每一条路径我们都有一条边要经过,那么我们只要保证我们走的边是

这条路径上的最大值就可以保证是最优解,

而这里面的最小值就是最小生成树产生的从上边界到下边界的最大值,所以直接跑个最小生成树就行了

这题有点像直接写过的一个water,可以直接跑生成树找下最大值过掉。。。

 

#include<bits/stdc++.h>
#define jb cout<<"jb";
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
        f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
#define min(a,b) ((a)<(b)?(a):(b))    
#define max(a,b) ((a)<(b)?(b):(a))
const double esp=1e-9;
const int maxn=6e5+2;
int n,m,k;
double x[maxn],y[maxn];
int v[maxn],v2[maxn];
bool vis[maxn];
double dis[maxn];
inline double ds(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
    n=read(),m=read();k=read();
    for(int i=1;i<=k;i++)
    x[i]=read(),y[i]=read();
    for(int i=1;i<=k;i++)
    dis[i]=m-y[i];
    dis[k+1]=m; dis[0]=1e9;
    double ans;
    while(1)
    {
        int mi=0;
        for(int i=1;i<=k+1;i++)
        {
            if(!vis[i]&&dis[i]<dis[mi])
             mi=i;
        }
        ans=max(ans,dis[mi]);
        vis[mi]=1;
        if(mi==k+1)
        {
            printf("%.8lf",ans/2.0);
            return 0;
        }
        for(int i=1;i<=k;i++)
        {
            dis[i]=min(dis[i],ds(x[i],y[i],x[mi],y[mi]));
        }
        dis[k+1]=min(dis[k+1],y[mi]);
    }
}
T1

T2God Knows

很难,又是数据结构题

线段树维护单调栈,建议看天皇skyh的博客,这里就只有个代码了

 

#include<bits/stdc++.h>
#define lid id<<1
#define rid id<<1|1
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
        f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
const int maxn=2e6+1;
const int inf=2e9;
int c[maxn],p[maxn],f[maxn],n;
inline int max(int x,int y){return x<y?y:x;}
inline int min(int x,int y){return y<x?y:x;}
struct segtree{
    int l,r,mn,mx,un;
}tr[maxn<<2];
inline int calc(int id,int nxt)
{
    if(tr[id].l==tr[id].r) 
    return tr[id].mx>nxt?tr[id].mn:inf;
    if(tr[rid].mx>nxt) return min(tr[lid].un,calc(rid,nxt));
    return calc(lid,nxt);
}
void pushup(int id)
{
    tr[id].mx=max(tr[lid].mx,tr[rid].mx);
    tr[id].mn=min(tr[rid].mn,tr[lid].un=calc(lid,tr[rid].mx));
}
void build(int id,int l,int r)
{
    tr[id].l=l,tr[id].r=r;
    tr[id].mn=tr[id].un=inf;
    tr[id].mx=-1;
    if(l==r) return ;
    int mid=(l+r)>>1;
    build(lid,l,mid);
    build(rid,mid+1,r);
}
int nxt;
inline int query(int id,int l,int r)
{    
    if(tr[id].l>=l&&tr[id].r<=r)
    {
        int ans=calc(id,nxt);
        nxt=max(tr[id].mx,nxt);
        return ans;
    }
    int ans=inf;
    if(r>=tr[rid].l) ans=min(ans,query(rid,l,r));
    if(l<=tr[lid].r) ans=min(ans,query(lid,l,r));
    return ans;
}
inline void update(int id,int pos,int i,int val)
{
    if(tr[id].l==tr[id].r)
    {
        tr[id].mn=val;
        tr[id].mx=i;
        return ;
    }
    if(pos<=tr[lid].r) update(lid,pos,i,val);
    if(pos>=tr[rid].l) update(rid,pos,i,val);
    pushup(id);
}
int main()
{
    //freopen("a.in","r",stdin);
    n=read();
    for(int i=1;i<=n;++i) p[i]=read();
    for(int i=1;i<=n;++i) c[i]=read();
    n++;
    p[n]=n;
    build(1,1,n);
    update(1,1,0,0);
    for(int i=1,k;i<=n;i++)
    {
        nxt=-1;
        k=query(1,0,p[i]-1)+c[i];
        update(1,p[i],i,k);
        if(i==n)
        printf("%d\n",k);
    }    
}
T2

 

T3Lost  may  music

这第一眼就是个斜率,可是没有学过,

求值公式其实就是斜率的复制

大体上就是维护一个突包,用倍增来维护单调栈,代码挺好写的

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
        f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
const int maxn=5e5+5;
int fa[maxn][21];
int n,c[maxn],dep[maxn];
int head[maxn],to[maxn*2],nxt[maxn*2],num;
int ans[maxn];
double calc(int x,int y){return 1.0*(c[y]-c[x])/(dep[y]-dep[x]);}
inline void add(int x,int y){to[++num]=y,nxt[num]=head[x];head[x]=num;}
void dfs(int x)
{
    int father=fa[x][0];
    for(int i=19;i>=0;i--)
    {
        if(fa[father][i]<=1) continue;
        if(calc(x,fa[father][i])<=calc(x,fa[fa[father][i]][0]))
        father=fa[father][i];
    }
    if(calc(x,father)<=calc(x,fa[father][0])&&father>1) father=fa[father][0];
    ans[x]=fa[x][0]=father;
    for(int i=1;i<=19;i++)
    fa[x][i]=fa[fa[x][i-1]][i-1];
    for(int i=head[x];i;i=nxt[i])
    {
        int y=to[i];
        dep[y]=dep[x]+1;
        dfs(y);
    }
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)    
    {
        c[i]=read();    
    }
    for(int i=2;i<=n;i++)
    {
        fa[i][0]=read();
        add(fa[i][0],i);
    }
    dfs(1);
    for(int i=2;i<=n;i++)
    {
        printf("%.8lf\n",-calc(i,ans[i]));
    }
}
T3

 

标签:lid,ch,noip,16,int,tr,rid,id,模拟
来源: https://www.cnblogs.com/JYFHYX/p/15020881.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有