2019-10-29

T1

T1 may be (some) in the eyes of some of the big brother is sent to a sub-themes (But I only have 10 minutes

Obvious to all this is an expansion of Euclid subject, we know that the coefficient \ (A, b \) , requires solving equations \ (ax + by = c \ ) and make \ (| x | + | y | \) to obtain the minimum value

We know that expanding Euclid can be solved \ (AX + by = gcd (A, b) \) , and if there is a positive number c satisfying \ (c \) % \ (gcd (A, b) == 0 \) , so \ (k = c / gcd ( a, b) \) then obviously \ (akx + bky = c \ ) so that \ (x = kx, y = ky \) we now amounts to solving \ (| x | + | y | \)

Obviously equation for a \ (ax + by = gcd ( a, b) \) and \ (a (x-nb) + b (y + na) = x \) are equivalent we can use our European expansion Reed seek out a few special solutions this modification, the condition of the solutions are obtained. And if you want to meet the conditions, then we need to let \ (x-nb \) is close to 0 or so \ (y + na \) is close to 0

Assuming that \ (a <b \) obviously if x changes so the change in y is very small so if you let a close unknowns x 0, y for the impact is relatively small, you can optimize it, will simplify the problem it (that is, at the beginning of \ (IF (a <b) swap (a, b) \) )

Then you can do (in fact, not above optimization can)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long 
using namespace std;
const int maxn=200010;
ll read(){
    ll 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*10+ch-'0';ch=getchar();};
    return x*f;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
    if(a%b==0){
        x=1;y=0;return b;
    }
    ll d=exgcd(b,a%b,x,y),t;
    t=y-a/b*x;
    y=x;
    x=t;
    return d;
}
ll n,num[maxn],a,b;
int main()
{
//  freopen("array.in","r",stdin);
//  freopen("arrayown.out","w",stdout);
    n=read();a=read();b=read();
    if(a<b) a^=b^=a^=b;
    ll d,x,y,ans=0;
    d=exgcd(a,b,x,y);
    a/=d;b/=d;
    //这里一定要除哦 不然要WA 
    for(ll i=1;i<=n;i++){
        num[i]=read();
        if(abs(num[i])%d)   
            return printf("-1"),0;
        ll X=x*(num[i]/d),Y=y*(num[i]/d);
        swap(X,Y);
        //x对应的系数大 y对应的系数小
        //因为要改变y 使得y 尽量为接近零的数 
        if(Y<0){//使得Y变正 
            X-=b*((-Y)/a+1);
            Y+=a*((-Y)/a+1);
        }
        X+=b*((Y)/a);
        Y-=a*((Y)/a);
        ans=ans+min(abs(X)+abs(Y),abs(X+b)+abs(Y-a));
    }
    printf("%lld",ans);
}

T2

Gugu Gu

#include<bits/stdc++.h>
#define L long long
#define vi vector<int>
#define pb push_back
using namespace std;
int n,m,w[200010],p;
L f[800010],g[800010];
struct orz
{
    int a,b,p;
}x[100010];
inline bool cmp(orz a,orz b)
{
    return a.a+a.b<b.a+b.b;
}
inline void down(int i)
{
    f[i<<1]+=g[i];
    g[i<<1]+=g[i];
    f[i<<1|1]+=g[i];
    g[i<<1|1]+=g[i];
    g[i]=0;
}
inline L query(int i,int j,int k,int p)
{
    if(j==k)
      return f[i];
    down(i);
    if(p<=j+k>>1)
      return query(i<<1,j,j+k>>1,p);
    else
      return max(f[i<<1],query(i<<1|1,(j+k>>1)+1,k,p));
}
inline void maxx(int i,int j,int k,int p,L q)
{
    f[i]=max(f[i],q);
    if(j!=k)
      {
       down(i);
       if(p<=j+k>>1)
         maxx(i<<1,j,j+k>>1,p,q);
       else
         maxx(i<<1|1,(j+k>>1)+1,k,p,q);
      }
}
inline void add(int i,int j,int k,int l,int r,int p)
{
    if(l<=j && k<=r)
      {
       f[i]+=p;
       g[i]+=p;
      }
    else
      {
       down(i);
       if(l<=(j+k>>1))
         add(i<<1,j,j+k>>1,l,r,p);
       if(r>(j+k>>1))
         add(i<<1|1,(j+k>>1)+1,k,l,r,p);
       f[i]=max(f[i<<1],f[i<<1|1]);
      }
}
int main()
{
    freopen("pair.in","r",stdin);
    freopen("pair.out","w",stdout);
    int i,j;
    L k;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
      {
       scanf("%d%d%d",&x[i].a,&x[i].b,&x[i].p);
       w[++m]=x[i].a;
       w[++m]=x[i].b;
      }
    sort(w+1,w+m+1);
    m=unique(w+1,w+m+1)-w;
    for(i=1;i<=n;i++)
      {
       x[i].a=lower_bound(w+1,w+m,x[i].a)-w;
       x[i].b=lower_bound(w+1,w+m,x[i].b)-w;
      }
    sort(x+1,x+n+1,cmp);
    for(p=1;p<m;p<<=1);
    for(i=1;i<=n;i++)
      {
       j=min(x[i].a,x[i].b);
       k=query(1,1,p,j)+x[i].p;
       maxx(1,1,p,x[i].a,k);
       if(x[i].b>x[i].a)
         add(1,1,p,x[i].a+1,x[i].b,x[i].p);
      }
    printf("%lld\n",f[1]);
    return 0;
}

T3

This question is then what in the eyes of big brother that's a problem, but the board konjac tune for a long time (M edges reason actually enter only the n

emmm for the first transfer distance between two particular points, or else they are directly connected, or else they are not directly connected, and by transferred from other points (note that only may be transferred from a special point other than the point, because if it is transferred from another special point to come, obviously more inferior because apparently transferred from the special point better)

So we can inspire with multi-source shortest path, and then for the two endpoints of an edge, if it is transferred from the different special points over, then you can update this special two points ans

As for proof. .

Not difficult to prove the source point i, the i and j point expansion without the expansion point i and j k adjacent
if the optimal path from i j k walked, then went to the expansion of the source k is the most excellent. So do this
law is correct.

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#define LL long long 
#define int long long
using namespace std;
const LL maxn=400010;
LL read(){
    LL 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*10+ch-'0';ch=getchar();}
    return x*f;
}
struct node
{
    int dis;
    int pos;
    bool operator <( const node &x )const
    {
        return x.dis < dis;
    }
};
priority_queue<node> q;
LL n,m,p,spe[maxn],tot=1,from[maxn],dis[maxn],ans[maxn<<1];
LL fir[maxn<<1],nxt[maxn<<1],to[maxn<<1],val[maxn<<1],inque[maxn<<1];
void add(LL x,LL y,LL z){
    nxt[++tot]=fir[x];fir[x]=tot;to[tot]=y;val[tot]=z;
    nxt[++tot]=fir[y];fir[y]=tot;to[tot]=x;val[tot]=z;
}
void dij()
{
    int rp,des;
    for(int i=1;i<=p;i++)
        q.push(node{0,spe[i]});
    while(!q.empty())
    {
        node tmp=q.top();
        q.pop();
        int x=tmp.pos;int y=tmp.dis;
        if(inque[x])    continue;
        inque[x]=true;
        for(rp=fir[x];rp;rp=nxt[rp])
        {
            des=to[rp];
            if(dis[des]>y+val[rp]){
            dis[des]=y+val[rp];
            from[des]=from[x];
            if(inque[des]==false)
            {
                q.push( ( node ){dis[des], des} );
            }
            }
                
        }
    }
}
signed main(){
//  freopen("distance.in","r",stdin);
//  freopen("distanceown.out","w",stdout);
    n=read();m=read();p=read();
    for(LL i=1;i<=p;i++)
        spe[i]=read();
    for(LL i=1,x,y,z;i<=m;i++){
        x=read();y=read();z=read();
        add(x,y,z);
    }
    for(LL i=1;i<=n;i++)
        dis[i]=1e18,ans[i]=1e18;
    for(LL i=1;i<=p;i++)
        dis[spe[i]]=0,from[spe[i]]=spe[i];
    dij();
    for(LL x=1;x<=n;x++){
        for(LL i=fir[x];i;i=nxt[i]){
            LL y=to[i];
            if(from[x]!=from[y])
                ans[from[x]]=min(ans[from[x]],dis[x]+dis[y]+val[i]);
        }
    }
    for(LL i=1;i<=p;i++)
    {
        if(i!=p)
            printf("%lld ",ans[spe[i]]);
        else printf("%lld\n",ans[spe[i]]);
    }
    return 0;
}

Probably that's the title of it, to be honest is not difficult, but because it's the same type of problems that led to today's little difference in the overall situation of duck ruffian

Guess you like

Origin www.cnblogs.com/mendessy/p/11761044.html