20191029

前言

  • 终于因为没有define int longlong挂分了……
  • 自己还是对扩欧理解不深刻,板子都不会只能现场yy,还打错了。
  • T2T3没有思路,还是没有培养思维。

T1

  • 用扩展欧几里得求方程的解。
  • 先将x,y其中一个值变成最靠近0的情况,然后暴力寻找更优解就行了。
  • 注意扩欧板子中要用a/b*x而不是x*a/b。
#include<cstdio>
#define ll long long
using namespace std;
int c;
inline int read(){
    int ss(0),pp(1);char bb(getchar());
    for(;bb<48||bb>57;bb=getchar())if(bb=='-')pp=-1;
    while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
    return ss*pp;
}
int exgcd(int a,int b,ll &x,ll &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int z=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return z;
}
inline ll _abs(ll x){
    return x<0?-x:x;
}
signed main(){
    //freopen("array.in","r",stdin);
    //freopen("1.out","w",stdout);
    int n=read(),a=read(),b=read(),g;
    if(a>b)a^=b^=a^=b;
    ll x,y,ans=0;
    g=exgcd(a,b,x,y);
    a/=g,b/=g;
    for(register int i=1;i<=n;++i){
        c=_abs(read());
        if(c%g)return puts("-1"),0;
        c/=g;
        ll zx=x*c,zy=y*c,z=zx/b;
        zx-=z*b,zy+=z*a;
        while(_abs(zx)+_abs(zy)>_abs(zx-b)+_abs(zy+a))zx-=b,zy+=a;
        while(_abs(zx)+_abs(zy)>_abs(zx+b)+_abs(zy-a))zx+=b,zy-=a;
        ans+=_abs(zx)+_abs(zy);
    }
    printf("%lld",ans);
    return 0;
}
View Code

T2

  • 先将给出的点对$(a_i,b_i)$按$a_i+b_i$的大小排序,然后就是一个队长快跑。
#include<cstdio>
#include<algorithm>
#include<queue>
#define ll long long
#define L tr[k].lc
#define R tr[k].rc
#define LC k<<1
#define RC k<<1|1
using namespace std;
int const N=2e5+5;
int n,tot;
struct node{
    int a,b,w;
    node(){}
    node(int x,int y,ll z):a(x),b(y),w(z){}
    friend bool operator < (node skyh,node yxs){
        return (skyh.a^yxs.a)?skyh.a>yxs.a:skyh.w<yxs.w;
    }
}s[N];
struct Pair{
    int fr,sc;
    Pair(){}
    Pair(int x,int y):fr(x),sc(y){}
}c[N];
int tt;
inline int read(){
    int ss(0);char bb(getchar());
    while(bb<48||bb>57)bb=getchar();
    while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
    return ss;
}
inline ll _max(ll x,ll y){
    return x>y?x:y;
}
struct Segment_Tree{
    struct ljj{
        int lc,rc;
        ll val,f;
    }tr[N<<2];
    void down(int k){
        int lk=k<<1;ll z=tr[k].f;
        tr[k].f=0;
        tr[lk].val+=z,tr[lk].f+=z;
        lk|=1,tr[lk].val+=z,tr[lk].f+=z;
        return ;
    }
    void build(int x,int y,int k){
        L=x,R=y;
        if(x==y)return ;
        int mid=x+y>>1;
        return build(x,mid,LC),build(mid+1,y,RC);
    }
    void add(int x,int y,ll z,int k){
        if(L>=x&&R<=y){tr[k].val+=z,tr[k].f+=z;return ;}
        int mid=L+R>>1;
        if(tr[k].f)down(k);
        if(x<=mid)add(x,y,z,LC);
        if(y>mid)add(x,y,z,RC);
        tr[k].val=_max(tr[LC].val,tr[RC].val);
        return ;
    }
    void modify(int x,ll y,int k){
        if(L==R){tr[k].val=_max(y,tr[k].val);return ;}
        if(tr[k].f)down(k);
        modify(x,y,k<<1|(x>(L+R>>1)));
        tr[k].val=_max(tr[LC].val,tr[RC].val);
        return ;
    }
    ll ask(int x,int y,int k){
        if(L>=x&&R<=y)return tr[k].val;
        int mid=L+R>>1;
        if(tr[k].f)down(k);
        if(x<=mid)return _max(ask(x,y,k<<1),y>mid?ask(x,y,k<<1|1):0ll);
        return ask(x,y,k<<1|1);
    }
}T;
int main(){
    //freopen("pair.in","r",stdin);
    //freopen("1.out","w",stdout);
    n=read();
    for(register int i=1;i<=n;++i)
        c[++tt]=Pair(s[i].a=read(),(i<<1)-1),
        c[++tt]=Pair(s[i].b=read(),i<<1),
        s[i].w=read();
    sort(c+1,c+tt+1,[](Pair skyh,Pair yxs){
        return skyh.fr<yxs.fr;
    });
    for(register int i=1;i<=tt;++i)
        ((c[i].sc&1)?s[c[i].sc+1>>1].a:s[c[i].sc+1>>1].b)=tot=tot+(c[i].fr!=c[i-1].fr);
    sort(s+1,s+n+1,[](node skyh,node yxs){
        return skyh.a+skyh.b<yxs.a+yxs.b;
    });
    T.build(1,tot,1);
    for(register int i=1;i<=n;++i){
        if(s[i].a<s[i].b)T.add(s[i].a+1,s[i].b,s[i].w,1);
        T.modify(s[i].a,T.ask(1,min(s[i].a,s[i].b),1)+s[i].w,1);
    }
    return printf("%lld",T.tr[1].val),0;
}
View Code

 T3

  • 多源最短路啊……思路很不错。
  • 记录每个节点的前驱,如果一条边的两个端点的前驱不同就更新答案。
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
int const N=2e5+5;
ll const lar=1e18;
int n,m,p;
int head[N],Next[N<<1],to[N<<1],w[N<<1],t=1;
int q[N];
struct Pair{
    int id;
    ll wt;
    Pair(){}
    Pair(int x,ll y):id(x),wt(y){}
}hp[N];
int tp,pre[N];
bool vis[N];
ll dis[N],ans[N];
inline int read(){
    int ss(0);char bb(getchar());
    while(bb<48||bb>57) bb=getchar();
    while(bb>=48&&bb<=57) ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
    return ss;
}
inline void add(int x,int y,int z){
    to[++t]=y,w[t]=z;
    Next[t]=head[x],head[x]=t;
    return ;
}
inline void _Swap(Pair &x,Pair &y){
    Pair z=x;
    x=y,y=z;
    return ;
}
inline void up(int x){
    while(x^1){
        if(hp[x].wt<hp[x>>1].wt) _Swap(hp[x],hp[x>>1]),x>>=1;
        else return ;
    }
}
inline void down(int x){
    int y=x<<1;
    while(y<=tp){
        if(y^tp && hp[y].wt>hp[y|1].wt) y|=1;
        if(hp[x].wt>hp[y].wt) _Swap(hp[x],hp[y]),x=y,y<<=1;
        else return ;
    }
}
inline void dijkstra(){
    while(tp){
        int x=hp[1].id;
        ll y=hp[1].wt;
        _Swap(hp[1],hp[tp--]),down(1);
        if(vis[x])continue;
        vis[x]=1;
        for(register int i=head[x],pnw=pre[x];i;i=Next[i])
            if(dis[to[i]]>y+w[i])
                pre[to[i]]=pnw,hp[++tp]=Pair(to[i],dis[to[i]]=y+w[i]),up(tp);
    }
    return ;
}
int main(){
    //freopen("distance.in","r",stdin);
    n=read(),m=read(),p=read();
    for(register int i=1;i<=p;++i) ans[q[i]=read()]=lar;
    for(register int i=1,ff,tt,ww;i<=m;++i)
        ff=read(),tt=read(),ww=read(),
        add(ff,tt,ww),add(tt,ff,ww);
    memset(dis,0x3f,n+1<<3);
    for(register int i=1;i<=p;++i) hp[i]=Pair(q[i],dis[q[i]]=0),pre[q[i]]=q[i];
    tp=p;
    dijkstra();
    for(register int i=1;i<=m;++i){
        int z=i<<1,x=to[z],y=to[z|1];
        if(pre[x]==pre[y])continue;
        ll le=dis[x]+dis[y]+w[z];
        x=pre[x],y=pre[y];
        if(le<ans[x])ans[x]=le;
        if(le<ans[y])ans[y]=le;
    }
    for(register int i=1;i<=p;++i)printf("%lld ",ans[q[i]]);
    return 0;
}
View Code
posted @ 2019-10-31 06:19  remarkable  阅读(124)  评论(0编辑  收藏  举报