JNday4-pm

预计分数 A + 30 + 0
实际分数 70 + 30 + 0

T1
这道题感觉并不难,先写出了暴力,对照暴力自己yy了差不多1h,调了出来,
然而没有写对拍,
正解:
这个东西的本质是更相减损术,相当于每次减去较小的那个数,然而直接进行
更相减损术太慢,我们可以通过辗转相除法来加快这个进程,并且在辗转相除
时累加答案

T2
当时做时并没有多长时间,相当于直接放弃了

kruscal算法求最大生成树,在并查集合并时,把原本的一个根连向另一个根
改成两个根都连向一个新建的节点,并把当前正在处理的边的权值赋给这个新建
节点做点权,这样形成的结构会是一课时,一个点的answer大致上是树的根到自己的
路径上,相邻两个节点的子树叶节点数的平方和。需要注意的是,父子两个节点权值
相同的情况,这个部分需要特殊处理。

T3
没听懂。。。。

 

 

T1 数列

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

ll a,b,c,ans;
int main(){
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
    scanf("%lld%lld",&a,&b);
    if (a<b) swap(a,b);
    c = a%b;
    while (c){
        ans += a/b;
        a = b;b = c;c = a%b;
    }
    ans += a/b;        
    ans++;
    printf("%lld\n",ans);
    return 0;
}

T2 车辆销售

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 510000;
typedef long long ll;
struct node
{
    int u, v, l;
    bool operator < (const node &no) const
    {
        return l > no.l;
    }
}e[N];
            
int n, m, newn;
int son[N][2];
int fa[N], size[N], value[N];
ll ans[N];

  
int read()
{
    char ch = getchar();
    int x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) {x = x*10+(ch-'0');ch=getchar();}
    return x;
}

int getf(int x)
{
    if (fa[x] == x) return x;
    fa[x] = getf(fa[x]);
    return fa[x];
}

void dfs(int u, int fa, ll cnt)
{
    ll delta = 0;
    if (fa)
    {
        if (value[u] == value[fa]) size[u] = size[fa];
        else delta = (ll)(size[fa] - size[u]) * (ll)(size[fa] - size[u]);
    }
    if (son[u][0])
    {
        dfs(son[u][0], u, cnt + delta);
        dfs(son[u][1], u, cnt + delta);
    }
    else ans[u] = cnt + delta;
}


int main()
{   
    freopen("car.in","r",stdin);
    freopen("car.out","w",stdout);
    n = read(), m = read();
    for (int i = 1; i <= m; i++)
    {
        e[i].u = read();
        e[i].v = read();
        e[i].l = read();
    }
    sort(e + 1, e + 1 + m);
    for (int i = 1; i <= n; i++) fa[i] = i;

    newn = n;
    for (int i = 1; i <= n; i++) size[i] = 1;

    
    for (int i = 1; i <= m; i++)
    {
        int u = getf(e[i].u), v = getf(e[i].v);
        if (u == v) continue;
        newn++;
        son[newn][0] = u;
        son[newn][1] = v;
        fa[u] = fa[v] = newn;
        fa[newn] = newn;
        value[newn] = e[i].l;
        size[newn] = size[u] + size[v];
    }
    dfs(newn, 0, 0);
    for (int i = 1; i <= n; i++)
        printf("%lld ", ans[i]);
    printf("\n");
    return 0;

    
}
        

T3 取数

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=1000010;
const LL inf=10000000;
int n,m,x,y,z,L,sum;
int cnt[N];
LL ans0,ans;
LL f[N],s[N];
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;
}
void solve(LL c)
{
    int i,a,tot=0;
    LL ss=0;
    memset(cnt,0,sizeof(cnt));
    memset(f,0,sizeof(f));
    for(i=1;i<=n;i++)
    {
        a=i-m;
        if(a>=1&&c-s[a]>0&&(f[a]>ss||(f[a]==ss&&cnt[a]<tot)))
        {
            ss=f[a];
            tot=cnt[a];
        }
        if(c-s[i]>0)
        {
            f[i]=ss+c-s[i];
            cnt[i]=tot+1;
        }
    }
    ans0=sum=0;
    for(i=1;i<=n;i++)
        if(f[i]>ans0||(f[i]==ans0&&sum>cnt[i]))
        {
            sum=cnt[i];
            ans0=f[i];
        }
//    printf("%d %lld %lld\n",sum,c,ans0);
}
int pd(LL c)
{
    solve(c);
    if(sum<L) return 1;
    else return 0;
}
int main()
{
    int a,b,c,i,j,k;
    LL l,r;
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    n=read();
    m=read();
    L=read();
    for(i=1;i<=n;i++)
        s[i]=read();
//    for(i=1;i<=n;i++)
//        if(i%m==1) ans+=(LL)s[i];
//    printf("%lld\n",ans);
    ans=0;
    l=0;
    r=(LL)inf*N/2;
    while(l<r-1)
    {
        LL mid=(l+r)/2;
        if(pd(mid)) l=mid;
        else r=mid;
    }
    if(pd(r))
    {
        solve(r);
        ans=(LL)L*r-ans0;
//        printf("%d\n",sum);
    }
    else
    {
        solve(l);
        ans=(LL)L*l-ans0;
    }
    printf("%lld\n",ans);
}
/*
6 5 2
100 1 1 1 1 100
*/

 

posted @ 2017-10-31 22:02  ioioioioioio  阅读(128)  评论(0编辑  收藏  举报