zoukankan      html  css  js  c++  java
  • 20180901南京网络赛题解

    20180901南京网络赛题解

    A. An Olympian Math Problem

    签到题,输出n-1即可。

    J. Sum

    MEANING

    对于一个数n,对其质因数分解,f(n)为其指数为1质因数的数量乘2,如果某一质因数指数为3或以上,f(n)=0,特别的,f(1) = 1。
    (S(n)=sum_{i=1}^nf(i))

    SOLUTION

    2e7的数据范围,考虑线性解法欧拉筛。prime[i]为保存的第i个素数。v[i]为当前枚举的数最小质因数。然后再用一个数组num[i]表示数i的最小质因数的指数。
    首先要理解欧拉筛的原理,然后对于欧拉筛中枚举的第i个数:
    (1)如果是质数,f[i] = 2。
    对于枚举的素数prime[j]:
    if prime[j]<i:f[i*prime[j]] = f[i]*2;
    if prime[j]i:f[i*prime[j]] = f[i]/2;
    (2)如果是合数,f[i] 已知。
    对于枚举的素数prime[j]:
    if prime[j]<v[i]:f[i*prime[j]] = f[i]*2;
    if prime[j]
    v[i]:f[i*prime[j]] 在num[i]大于等于3时为0.否则为f[i]/2;

    CODE

    #define FILE_IN() freopen("C:\Users\dmt\Desktop\in.txt","r",stdin);
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 20000005;
    
    ll f[MAXN];
    int v[MAXN],prime[MAXN],num[MAXN];
    
    void primes() {
        memset(v,0,sizeof(v));
        int m = 0;
        for(int i=2; i<=MAXN-3; i++) {
            if(v[i]==0) {
                v[i] = i;
                prime[++m] = i;
                f[i] = 2;
                num[i] = 1;
            }
            for(int j=1; j<=m; j++) {
                if(prime[j]>v[i]||prime[j]>(MAXN-3)/i)break;
                v[i*prime[j]] = prime[j];
                if(prime[j]<v[i]){num[i*prime[j]] = 1;f[i*prime[j]] = f[i]*2;}
                else {
                    num[i*prime[j]] = num[i]+1;
                    if(num[i*prime[j]]<=2)f[i*prime[j]] = f[i]/2;
                    else f[i*prime[j]] = 0;
                }
            }
        }
    }
    
    int main() {
    //    FILE_IN();
        fill(f,f+MAXN,1);
        f[1] = 1;
        primes();
        for(int i = 2;i<=MAXN-5;i++)f[i]+=f[i-1];
        int T;
        for(scanf("%d",&T); T; T--) {
            int n;
            scanf("%d",&n);
            printf("%lld
    ",f[n]);
        }
        return 0;
    }
    

    L. Magical Girl Haze

    MEANING

    给一个有向图G(N,M)。你可以选择最多K条边使其权值为0,问顶点1到N的最短路。

    SOLUTION

    分层图最短路,每个点记录k个状态的最短路,跑dijkstra。

    CODE

    #define FILE_IN() freopen("C:\Users\dmt\Desktop\in.txt","r",stdin);
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 100005;
    const ll INF = 200000000000005ll;
    struct edge{
        int v,nex,w;
    }ed[MAXN*2];
    
    int head[MAXN],tot,n,m,k;
    
    void addedge(int u,int v,int w){
        tot++;
        ed[tot].v = v;
        ed[tot].w = w;
        ed[tot].nex = head[u];
        head[u] = tot;
    }
    
    ll d[MAXN][11];
    bool vis[MAXN][11];
    struct node{
        ll d;
        int ind,used;
    };
    bool operator <(node a,node b){
        return a.d>b.d;
    }
    priority_queue<node>q;
    
    void dij(){
        for(int i=0;i<=n;i++)for(int j=0;j<=10;j++){d[i][j] = INF;vis[i][j]=0;}
        for(int i=0;i<=k;i++)d[1][i] = 0;
        q.push({0ll,1,0});
        while(q.size()){
            node cur = q.top();
            q.pop();
            int u = cur.ind,used = cur.used;
            if(vis[u][used])continue;
            vis[u][used] = 1;
            for(int i = head[u];i;i=ed[i].nex){
                int v = ed[i].v,w = ed[i].w;
                if(d[v][used]>d[u][used]+w){
                    d[v][used] = d[u][used]+w;
                    q.push({d[v][used],v,used});
                }
                if(used+1<=k&&d[v][used+1]>d[u][used]){
                    d[v][used+1] = d[u][used];
                    q.push({d[v][used+1],v,used+1});
                }
            }
        }
    }
    
    void init(){
        tot = 0;
        memset(head,0,sizeof head);
    }
    
    int main() {
    //    FILE_IN();
        int T;
        for(scanf("%d",&T);T;T--){
            scanf("%d%d%d",&n,&m,&k);
            init();
            for(int i=0;i<m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
            }
            dij();
            ll ans = INF;
            for(int i=0;i<=10;i++){
                ans  = min(ans,d[n][i]);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    【BZOJ3518】点组计数 欧拉函数
    【BZOJ3677】[Apio2014]连珠线 换根DP
    【BZOJ3678】wangxz与OJ Splay
    【BZOJ3935】Rbtree 树形DP
    【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树
    (转)Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
    string.Format出现异常"输入的字符串格式有误"的解决方法
    c# winForm使用Aspose.Cells读取CSV文件中文乱码问题
    PowerDesigner15.1给自定义架构表字段添加MS_Description出错
    MongoDB 多条件组合查询
  • 原文地址:https://www.cnblogs.com/NeilThang/p/9572237.html
Copyright © 2011-2022 走看看