NWERC2013题解

1 篇文章 0 订阅

链接:http://codeforces.com/gym/100405
这场yyn给我们找的用来练手的比赛,虽然很水,但我还是想写一下简要题解

A:N个点N条边提示我们去求最小生成树,然后枚举两个距离与距离表不符的点,选一对距离最小的,然后添加这条非树边。证明还有点混乱。。。(坑)

B:因为要求平面图,画一下就知道最大团不会超过4,暴力枚举就可以通过这道题

C:因为数据范围比较小,可以暴力dp在每个位置出现的概率

D:这题有很多组,卡时间比较厉害,如果按行转移的话每一行最多有1000左右的状态,复杂度就是1000*1000*7*7有可能会tle,但如果按列转移每一列的状态最多只有C(7,3)=35,暴力把这些状态搜出来,然后做一个35*35*7*7的dp就可以通过了

E:首先我们考虑先把第一层拆成 xy 的形式,因为 (ab)c=abc ,也就是说第二层的可以随便放回到第一层,因此我们先把第一层提出一个最大的b乘到第二层里面去。而对于第二层,由于 9587<214 ,因此第二层分解质因数结束后指数不会超过13,乘上第三层之后也不会超过13*9587,因此我们只需要暴力枚举第二层的公共次数,累加起来就可以了,这题可能不太好说,可以参考一下代码

#include<bits/stdc++.h>
using namespace std;
typedef long long Int;
const Int Maxn=130000;
typedef pair<int,int>pi;
Int dp[Maxn];
vector<Int>has[Maxn];
void prepare()
{
    for(Int i=2;i<Maxn;i++)
    {
        for(Int j=i*i,t=2;j<Maxn;j*=i,t++)
            has[j].push_back(t);
    }
    for(Int i=2;i<Maxn;i++)
    {
        dp[i]=1;
        for(Int x:has[i])dp[i]+=dp[x];
    }
}
void f(vector<pi>&v,int x)//对x分解质因数
{
    v.clear();
    for(int i=2;i*i<=x;i++)
        if(x%i==0)
        {
            int t=1;
            x/=i;
            while(x%i==0)x/=i,t++;
            v.push_back(pi(i,t));
        }
    if(x!=1)v.push_back(pi(x,1));
}
int main()
{
    prepare();
    Int a,b,c;
    while(scanf("%lld^%lld^%lld",&a,&b,&c)!=EOF)
    {
        vector<pi>va,vb;
        f(va,a);
        int gc=0;
        for(pi u:va)gc=__gcd(gc,u.second);
        f(va,gc);
        f(vb,b);
        for(int i=0;i<vb.size();i++)
        {
            vb[i].second*=c;
        }
        for(pi u:va)
        {
            bool flag=0;
            for(int i=0;i<vb.size()&&vb[i].first<=13;i++)
            {
                if(u.first==vb[i].first)
                {
                    vb[i].second+=u.second;
                    flag=1;
                    break;
                }
            }
            if(!flag)vb.push_back(u);
        }
        int maxx=0;
        for(pi u:vb)maxx=max(maxx,u.second);
        Int ans=0;
       // for(pi u:vb)printf("%d^%d\n",u.first,u.second);
        for(int i=2;i<=maxx;i++)
        {
            Int tp=1;
            for(pi u:vb)tp=tp*(u.second/i+1);
            tp--;
            ans+=tp*dp[i];
            //printf("i=%d ans=%lld\n",i,ans);
        }printf("%lld\n",ans);
    }
}

F:只需要根据差值(还需要跳过多少天)进行转换,注意加入这天在新日历上应该被跳过算的时候是不要算的。

G:数学公式题,根据相似三角形算下就可以了

H:暴力模拟每一个整数秒,由这一秒作为起点,用于同一秒出生的车假如速度不同是不会在除了起点之外的地方相遇的,因此只要和之前可能和他相遇的车求交就可以了,由于是相遇时间可能不是整数,可以搞一个分数类求,统计一下相同时间的有多少辆车,更新一下答案就可以通过这题。不知道为什么过的人这么少。。。。

I:这题更加令人费解。。。。赤裸裸的区间dp,虽然n有1000,但这种题很难看出有其他做法

J:这题比较精妙。构造方法是从每个节点没有苹果开始,把苹果一个一个插入,假如左子树比右子树多一个苹果,就向右子树差,反之类似,即每一时刻都保持是平衡的,假如两边苹果一样多,就都尝试一下,看能否找到一个原来就放有苹果的点插入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值