20210717-NOIP18

内网链接


T1 导弹袭击
每个型号看成点 ((frac{1}{a_i},frac{1}{b_i})),维护下凸壳。

#include<bits/stdc++.h>
#define ld long double
using namespace std;
const int N=310000;
int q[N],n,fry,frx,top,nxt[N];
ld k[N];
bool ans[N];
struct dian
{
    int id,x,y;
//     bool operator<(const dian & a)const{
//        return x>a.x||(x==a.x&&y>a.y);
//    }
}d[N];
bool operator <(const dian &a,const dian &b)
{
    return a.x>b.x||(a.x==b.x&&a.y>b.y);
}
ld K(dian i,dian j)
{
    return (ld)i.x*j.x*(j.y-i.y)/((ld)i.y*j.y*(j.x-i.x));
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        d[i].id=i;
        scanf("%d%d",&d[i].x,&d[i].y);
        if(fry<d[i].y||(d[i].y==fry&&frx<d[i].x))
        {
            fry=d[i].y;
            frx=d[i].x;
        }
    }
//    sort(d+1,d+1+n,cmp);
    sort(d+1,d+1+n);
    q[++top]=1;
    for(int i=2;i<=n&&frx<=d[i].x;i++)
    {
        if(d[q[top]].x==d[i].x)
        {
            if(d[q[top]].y==d[i].y)
            {
                nxt[d[i].id]=nxt[d[q[top]].id];
                nxt[d[q[top]].id]=d[i].id;
            }
            continue;
        }
        while(top>1&&k[top]>K(d[q[top]],d[i]))
            top--;
        q[++top]=i;
        k[top]=K(d[q[top-1]],d[i]);
    }
    for(;top;top--)
    {
        for(int i=d[q[top]].id;i;i=nxt[i])
            ans[i]=1;
    }
    for(int i=1;i<=n;i++)
        if(ans[i])
            printf("%d ",i);
    printf("
");
    return 0;
}

T2 炼金术士的疑惑
高斯消元裸题,读入略烦。

#include<bits/stdc++.h>
using namespace std;
const int N=210;
const long double x=0.000001;
inline int read()
{
    int s=0,w=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
inline long double _fabs(long double x)
{
    if(x<0)
        return -x;
    else
        return x;
}
int n,m;
char opt[10];
long double a[N][N],d[N],num;
bool vis[N];
map<string,int> hah;
string s;
int main()
{
    n=read();
    int w;
    for(int i=1;i<=n+1;i++)
    {
        w=1;
        for(int j=1;j<=200;j++)
        {
            cin>>num>>s;num*=w;
            if(hah.find(s)==hah.end())
            {
                hah[s]=++m;
            }
            a[i][hah[s]]=num;
            scanf("%s",opt+1);
            if(opt[1]=='=')
            {
                w=-1;
            }
            else if(opt[1]=='H')
            {
                if(i<=n)
                {
                    scanf("%Lf",&d[i]);
                }
                break;
            }
        }
    }
    for(int i=1;i<=n;i++)
        a[i][m+1]=d[i];
    for(int i=1;i<=n;i++)
    {
        int maxx=i;
        for(int j=i+1;j<=n;j++)
        {
            if(_fabs(a[j][i])>_fabs(a[maxx][i]))
                maxx=j;
        }
        if(maxx!=i)
        for(int j=1;j<=m+1;j++)
        {
            swap(a[i][j],a[maxx][j]);
        }
        if(_fabs(a[i][i])<1e-8)
            continue;
        long double chu=a[i][i];
        for(int j=i;j<=m+1;j++)
            a[i][j]/=chu;
        for(int j=1;j<=n+1;j++)
        {
            if(j==i)
                continue;
            long double chu=a[j][i];
            for(int k=i;k<=m+1;k++)
            {
                a[j][k]-=a[i][k]*chu;
            }
        }
    }
    if(a[n+1][m+1]-x<0&&a[n+1][m+1]+x>0)
        printf("0.0
");
    else
        printf("%.1Lf
",-a[n+1][m+1]);
    return 0;
}
/*
2
1 C + 1 O2 = 1 CO2 H= -393.5
1 CO + 0.5 O2 = 1 CO2 H= -283.0
2 C + 1 O2 = 2 CO H= ?
*/

T3
老司机的狂欢。
二分答案做第一问。
image

#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x&(-x))
using namespace std;
const int N=110000;
int n,k,l,r,mid,goa[N],ygoa[N],minn[N][23],ans,b[N],tot,sta[N],fa[N][23],tp;
double tree[N];
bool flag;
inline int _max(int a,int b)
{
    return a>b?a:b;
} 
void plu(int cur,int v)
{
    while(cur<=n)
    {
        tree[cur]=_max(tree[cur],v);
        cur+=lowbit(cur);
    }
    return; 
}
int find(int cur)
{
    int res=0;
    while(cur>0)
    {
        res=_max(res,tree[cur]);
        cur-=lowbit(cur);
    }
    return res; 
}
struct peopl
{
    int x,a,id;
}p[N];
inline int read()
{
    int s=0,w=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
bool cmp(const peopl &a,peopl &b)
{
    return a.x<b.x;
}
bool check(int x)
{
    memset(tree,0,sizeof(tree));
    for(int i=n;i>=1;i--)
    {
        ygoa[i]=goa[i]=2.0*p[i].x+1.0*p[i].a*x*x;
    }
    sort(goa+1,goa+1+n);
    for(int i=1;i<=n;i++)
    {
        ygoa[i]=lower_bound(goa+1,goa+1+n,ygoa[i]) - goa;
        plu(ygoa[i],find(ygoa[i]-1)+1);
    }
    if(find(n)>=k)
    {
        if(find(n)>k)
        {
            flag=1;
        }
        else
            flag=0;
        return 1;
    }
    return 0;
}
struct node
{
    int dis,id;
}c[N];
bool operator < (const node &aa,const node &bb){
    if(aa.dis!=bb.dis)return aa.dis<bb.dis;
    int xx=aa.id;
    int yy=bb.id;
    int mina=aa.id,minb=bb.id;
    for(int i=20;i>=0;i--){
        if(fa[xx][i]!=fa[yy][i]){
            mina=min(mina,minn[xx][i]);
            minb=min(minb,minn[yy][i]);
            xx=fa[xx][i];
            yy=fa[yy][i];
        }
    }
    return mina>minb;
}
node ask(int x){
    node anss=node{0,0};
    for(;x;x-=x&-x)anss=max(anss,c[x]);
    return anss;
}
void add(int x,node w){
    for(;x<=tot;x+=x&-x)
    c[x]=max(c[x],w);
    return ;
}
void slove(int x)
{
    for(int i=n;i>=1;i--)
    {
        b[i]=ygoa[i]=goa[i]=2.0*p[i].x+1.0*p[i].a*x*x;
    }
    sort(goa+1,goa+1+n);
    tot=unique(goa+1,goa+1+n)- goa -1;
    for(int i=1;i<=n;i++)
    {
        b[i]=lower_bound(goa+1,goa+1+tot,b[i]) -goa;
    }
    for(int i=1;i<=n;i++)
    {
        node x=ask(b[i]-1);
        fa[p[i].id][0]=minn[p[i].id][0]=x.id;
        for(int j=1;j<=20;j++){
            fa[p[i].id][j]=fa[fa[p[i].id][j-1]][j-1];
            minn[p[i].id][j]=min(minn[fa[p[i].id][j-1]][j-1],minn[p[i].id][j-1]);
        }
        node y=node{x.dis+1,p[i].id};
        add(b[i],y);
    }
    int ss=ask(n).id;
    while(ss){
        sta[++tp]=ss;
        ss=fa[ss][0];    
    }
    sort(sta+1,sta+tp+1);
    for(int i=1;i<=tp;i++){
        printf("%lld
",sta[i]);
    }
    return ;
} 
signed main()
{
//    freopen("driver4.in","r",stdin);
    n=read();k=read();
    for(int i=1;i<=n;i++)
    {
        p[i].x=read();
        p[i].a=read();
        p[i].id=i;
    }
    l=0;r=86400;
    sort(p+1,p+1+n,cmp);
    flag=1;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(check(mid))
        {
            l=mid+1;
            ans=mid;
        }
        else
        {
            r=mid-1;
        }
    }
    printf("%lld
",ans);
    if(flag)
        puts("-1");
    else
        slove(ans);
    return 0;
}
原文地址:https://www.cnblogs.com/HKHbest/p/15029228.html