zoukankan      html  css  js  c++  java
  • 2017 Multi-University Training Contest

    rank 75/739

    1003 Counting Divisors

    筛法求出l到r区间内各个数字质因子的个数,对于每个数,d(x) = ∏(1+k*pi),pi为质因子指数。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1000005;
    const long long mod=998244353;
    int T,tot;
    bool is_prime[maxn];
    long long l,r,K,prime[maxn],num[maxn],temp[maxn];
    vector<long long> G[maxn];
    int sieve() {
        int p=0;
        memset(is_prime,0,sizeof is_prime);
        is_prime[0]=is_prime[1]=1;
        for (int i=2;i<maxn;++i) {
            if (!is_prime[i]) {
                prime[p++]=i;
                for (int j=2*i;j<maxn;j+=i)
                    is_prime[j]=1;
            }
        }
        return p;
    }
    void print() {
        for (int i=0;i<=r-l;++i) {
            printf("%I64d: ",i+l);
            for (int j=0;j<(int)G[i].size();++j)
                printf("%I64d ",G[i][j]);
            putchar('
    ');
        }
    }
    int main()
    {
        tot=sieve();
        scanf("%d",&T);
        while (T--) {
            scanf("%I64d%I64d%I64d",&l,&r,&K);
            for (long long i=0;i<=r-l;++i)
                num[i]=i+l,temp[i]=1;
            for (int i=0;i<tot;++i) {
                long long p=prime[i];
                for (long long j=(l+p-1)/p*p;j<=r;j+=p) {
                    long long &tj=num[j-l];
                    long long cnt=0;
                    while (tj%p==0) {
                        tj/=p;
                        ++cnt;
                    }
                    temp[j-l]=temp[j-l]*(K*cnt+1)%mod;
                }
            }
            for (int i=0;i<=r-l;++i)
                if (num[i]>1)
                    temp[i]=(temp[i]*(K+1))%mod;
            long long res=0;
            for (int i=0;i<=r-l;++i)
                res=(res+temp[i])%mod;
            cout<<res<<endl;
        }
        return 0;
    }
    1003

    1004 Dirt Ratio

    二分答案[0,1]C,区间内种类个数M,区间长度N,那么有M/N <=  c 为 true。转化为M - C * N   <=  0。遍历N,线段树维护以i为结尾的答案,如果1,i区间最小值小于等于0 返回true。

    #include <bits/stdc++.h>
    const long long mod = 1e9+7;
    const double ex = 1e-10;
    #define inf 0x3f3f3f3f
    using namespace std;
    map <int ,int> M;
    int a[60005];
    const int maxn = 60005;
    struct node
    {
        double val;
        double addmark;
    } ST[4*maxn+5];
    double A[maxn];
    int N;
    //修改求和还是维护区间最小值
    double operation(double a,double b)
    {
        //return a+b;
        return min(a,b);
    }
    //修改求和还是维护区间最小值
    void change(int pos,double addmark,int l)
    {
        ST[pos].val +=addmark;
    }
    void build(int root,int ibegin,int iend)
    {
        ST[root].addmark = 0;
        if (ibegin==iend)
            ST[root].val = A[ibegin];
        else
        {
            int mid = (ibegin+iend)/2;
            build(2*root,ibegin,mid);
            build(2*root+1,mid+1,iend);
            ST[root].val = operation(ST[root*2].val,ST[root*2+1].val);
        }
    }
    void push_down(int root,int l)
    {
        if (ST[root].addmark == 0) return;
        double  addmark = ST[root].addmark;
        ST[root*2].addmark+=addmark;
        ST[root*2+1].addmark+=addmark;
        change(root*2,addmark,l-l/2);
        change(root*2+1,addmark,l/2);
        ST[root].addmark = 0;
    }
    double query(int root,int ibegin,int iend,int qbegin,int qend)
    {
        if (ibegin > qend || iend < qbegin)
            return 1e233;//
        if (ibegin>=qbegin&&iend<=qend)
            return ST[root].val;
        push_down(root,iend-ibegin+1);
        int mid = (ibegin+iend)/2;
        return operation(query(root*2,ibegin,mid,qbegin,qend),query(root*2+1,mid+1,iend,qbegin,qend));
    }
    void updata(int root,int ibegin,int iend,int qbegin,int qend,double addmark)
    {
        if (ibegin > qend || iend < qbegin)
            return ;//
        if (ibegin>=qbegin&&iend<=qend)
            {
                ST[root].addmark+=addmark;
                change(root,addmark,iend-ibegin+1);
                return;
            }
        push_down(root,iend-ibegin+1);
        int mid = (ibegin+iend)/2;
        updata(root*2,ibegin,mid,qbegin,qend,addmark);
        updata(root*2+1,mid+1,iend,qbegin,qend,addmark);
        ST[root].val = operation(ST[root*2].val,ST[root*2+1].val);
    }
    int last[60005];
    int t[60005];
    bool check(double ans)
    {
        for (int i = 1; i<=N; i++)
            A[i] = 0;
        build(1,1,N);
        for (int i = 1;i<=N; i++)
        {
            updata(1,1,N,last[i]+1,i,1.0);
            updata(1,1,N,1,i,-ans);
            if (query(1,1,N,1,i) < 0) return true;
        }
        return false;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
    
            scanf("%d",&N);
            for (int i = 1;i<=N;i++)
                t[i] = last[i] = 0;
            for (int i = 1;i<=N;i++)
            {
                scanf("%d",&a[i]);
                if (t[a[i]] == 0)
                {
                    last[i] = 0;
                }
                else
                {
                    last[i] = t[a[i]];
                }
                t[a[i]] = i;
            }
            int cnt = 0;
            double l = 0;
            double r = 1+ex;
            while (cnt++<=15)
            {
                double mid = (l+r)/2;
                if (check(mid))
                    r = mid;
                else l = mid;
            }
            printf("%.10f
    ",l);
        }
        return 0;
    1004

    1005 Lazy Running

    取左右最小值W,转化为最短路,求%2*W的最短路。可以知道能够通过所求最短路和 重复来回走T次W来构造所有可能。

    #include <bits/stdc++.h>
    const long long mod = 1e9+7;
    const double ex = 1e-10;
    #define inf 0x3f3f3f3f3f3f3f3f
    using namespace std;
    long long dis[6][60002];
    int inq[6][60002];
    long long a[6][6];
    typedef pair<int,long long> pii;
    long long W;
    void spfa()
    {
        memset(dis,inf,sizeof(dis));
        memset(inq,0,sizeof(inq));
        queue <pii> Q;
        Q.push(make_pair(1,0));
        dis[1][0] = 0;
        inq[1][0] = 1;
        while (!Q.empty()){
            int u = Q.front().first;
            long long  k = Q.front().second;
    
            if (dis[(u+1)%4][( k + a[u][ (u+1) % 4 ] ) % (2*W)]>dis[u][k] + (long long) a[u][ (u+1) % 4 ]){
                dis[(u+1)%4][( k + a[u][ (u+1) % 4 ] ) % (2*W)] = dis[u][k] + (long long)a[u][ (u+1) % 4 ];
                if (!inq[(u+1)%4][( k + a[u][ (u+1) % 4 ] ) % (2*W)]){
                    Q.push(make_pair((u+1)%4,( k + a[u][ (u+1) % 4 ] ) % (2*W)));
                    inq[(u+1)%4][( k + a[u][ (u+1) % 4 ] ) % (2*W)] = 1;
                }
            }
            if (dis[(u+3)%4][( k + a[u][ (u+3) % 4 ] ) % (2*W)]>dis[u][k] + (long long) a[u][ (u+3) % 4 ]){
                dis[(u+3)%4][( k + a[u][ (u+3) % 4 ] ) % (2*W)] = dis[u][k] + (long long)a[u][ (u+3) % 4 ];
                if (!inq[(u+3)%4][( k + a[u][ (u+3) % 4 ] ) % (2*W)]){
                    Q.push(make_pair((u+3)%4,( k + a[u][ (u+3) % 4 ] ) % (2*W)));
                    inq[(u+3)%4][( k + a[u][ (u+3) % 4 ] ) % (2*W)] = 1;
                }
            }
            Q.pop();
            inq[u][k] = 0;
        }
    }
    int main()
    {
        int N;
        cin >> N;
        while (N--){
            long long K;
            cin >> K;
            for (int i = 0; i<=3; i++){
                long long  t;
                cin >> t;
                a[i][(i+1)%4] = t;
                a[(i+1)%4][i] = t;
            }
            W = min(a[1][2],a[0][1]);
            spfa();
            long long ans = inf;
            for (int i = 0 ; i<2*W ; i++){
                if (dis[1][i]>=K) ans = min(ans,dis[1][i]);
                else ans = min (ans,dis[1][i] + 2*W *((K-dis[1][i] + 2*W-1)/(2*W)) );
            }
            cout << ans <<endl;
        }
        return 0;
    }
    1005

    1007 Matching In Multiplication【补】

    一个特殊的二分图,找到图上的环,对于环上的点分为两种选择分为ai,bi;找到图上的链,对于这部分链,选择唯一为cj。所有完美匹配的乘积的和显然就是(ai+bi)cj。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=300015;
    const long long mod=998244353;
    typedef pair<int,long long> pil;
    int deg[maxn],T,n,vis[maxn<<1],tot,head[maxn<<1],ok,pb,used[maxn<<1];
    long long temp[maxn][2],res;
    vector<long long> cir;
    queue <int> Q;
    struct ee {
        int to,next;
        long long w;
        bool flag;
    } edge[maxn<<2];
    void addedge(int u,int v,long long w) {
        edge[tot].w=w;
        edge[tot].to=v;
        edge[tot].next=head[u];
        edge[tot].flag=0;
        head[u]=tot++;
        edge[tot].w=w;
        edge[tot].to=u;
        edge[tot].next=head[v];
        edge[tot].flag=0;
        head[v]=tot++;
    };
    void dfs(int u,int fa) {
        if (used[u]) return;
        if (vis[u]&&!used[u]) {
            ok=1;
            pb=u;
            return;
        }
        vis[u]=1;
        for (int i=head[u];~i;i=edge[i].next) {
            if (edge[i].flag)
                continue;
            if (edge[i].to == fa) continue;
            dfs(edge[i].to,u);
            if (ok) {
                edge[i].flag=true;
                edge[i^1].flag=true;
                cir.push_back(edge[i].w);
                used[u]=1;
                if (pb==u)
                    ok=0;
                return;
            }
        }
    }
    void dfs2(int u,int col) {
        vis[u]=1;
        for (int i=head[u];~i;i=edge[i].next) {
            if (edge[i].flag)
                continue;
            if (vis[edge[i].to])
                continue;
            if (!col){
                res=res*edge[i].w%mod;
                dfs2(edge[i].to,!col);
            }
            else{
                deg[edge[i].to-n]--;
                if (deg[edge[i].to-n] == 1) dfs2(edge[i].to,!col);
            }
    
        }
    }
    int main()
    {
        scanf("%d",&T);
        while (T--) {
            scanf("%d",&n);
            tot=0;
            memset(vis,0,(2*n+2)*sizeof vis[0]);
            memset(head,-1,(2*n+2)*sizeof head[0]);
            memset(deg,0,(n+1)*sizeof deg[0]);
            memset(used,0,(2*n+2)*sizeof used[0]);
    
            for (int i=1;i<=n;++i) {
                int v1,v2;
                long long w1,w2;
                scanf("%d%I64d%d%I64d",&v1,&w1,&v2,&w2);
                addedge(i,v1+n,w1);
                addedge(i,v2+n,w2);
                ++deg[v1];
                ++deg[v2];
            }
            for (int i=0;i<=n;++i)
                temp[i][0]=temp[i][1]=1;
            int cnt=0;
            for (int i=1;i<=n;++i)
                if (!vis[i]) {
                    ok=0;
                    cir.clear();
                    dfs(i,-1);
                    if (cir.size()==0) continue;
                    ++cnt;
                    for (int j=0;j<(int)cir.size();++j)
                        temp[cnt][j&1]=temp[cnt][j&1]*cir[j]%mod;
                }
            res=1;
            for (int i=1;i<=cnt;++i)
                res=res*((temp[i][0]+temp[i][1])%mod)%mod;
            memset(vis,0,sizeof vis);
            for (int i=n+1;i<=(n<<1);++i)
                if (deg[i-n]==1)
                    dfs2(i,0);
            cout<<res<<endl;
        }
        return 0;
    }
    1007

    1009 Questionnaire

    m = 2 的时候显然模数只有0或1,取多的那个。

    #include <bits/stdc++.h>
    using namespace std;
    int T,cnta,cntb,t,n,res;
    int main()
    {
        scanf("%d",&T);
        while (T--) {
            cnta=cntb=0;
            scanf("%d",&n);
            for (int i=1;i<=n;++i) {
                scanf("%d",&t);
                if (t&1)
                    ++cnta;
                else
                    ++cntb;
            }
            if (cnta>cntb)
                res=1;
            else
                res=0;
            printf("2 %d
    ",res);
        }
        return 0;
    }
    1009

    1011 Time To Get Up

    模拟

    #include <bits/stdc++.h>
    const long long mod = 1e9+7;
    const double eX = 1e-10;
    #define inf 0X3f3f3f3f
    using namespace std;
    string s[10];
    string ans[10];
    int get(int u)
    {
        if (s[2][u+2] == 'X') return 10;
        else if (s[1][u+2]=='X'&&s[4][u+2]=='X'&&s[2][u]=='X'&&s[2][u+3]=='X'&&s[5][u]=='X'&&s[5][u+3]=='X'&&s[7][u+2]=='X') return 8;
        else if (s[1][u+2]=='X'&&s[4][u+2]=='.'&&s[2][u]=='X'&&s[2][u+3]=='X'&&s[5][u]=='X'&&s[5][u+3]=='X'&&s[7][u+2]=='X') return 0;
        else if (s[1][u+2]=='.'&&s[4][u+2]=='.'&&s[2][u]=='.'&&s[2][u+3]=='X'&&s[5][u]=='.'&&s[5][u+3]=='X'&&s[7][u+2]=='.') return 1;
        else if (s[1][u+2]=='X'&&s[4][u+2]=='X'&&s[2][u]=='.'&&s[2][u+3]=='X'&&s[5][u]=='X'&&s[5][u+3]=='.'&&s[7][u+2]=='X') return 2;
        else if (s[1][u+2]=='X'&&s[4][u+2]=='X'&&s[2][u]=='.'&&s[2][u+3]=='X'&&s[5][u]=='.'&&s[5][u+3]=='X'&&s[7][u+2]=='X') return 3;
        else if (s[1][u+2]=='.'&&s[4][u+2]=='X'&&s[2][u]=='X'&&s[2][u+3]=='X'&&s[5][u]=='.'&&s[5][u+3]=='X'&&s[7][u+2]=='.') return 4;
        else if (s[1][u+2]=='X'&&s[4][u+2]=='X'&&s[2][u]=='X'&&s[2][u+3]=='.'&&s[5][u]=='.'&&s[5][u+3]=='X'&&s[7][u+2]=='X') return 5;
        else if (s[1][u+2]=='X'&&s[4][u+2]=='X'&&s[2][u]=='X'&&s[2][u+3]=='.'&&s[5][u]=='X'&&s[5][u+3]=='X'&&s[7][u+2]=='X') return 6;
        else if (s[1][u+2]=='X'&&s[4][u+2]=='.'&&s[2][u]=='.'&&s[2][u+3]=='X'&&s[5][u]=='.'&&s[5][u+3]=='X'&&s[7][u+2]=='.') return 7;
        else return 9;
    
    }
    int main()
    {
        ios::sync_with_stdio(false);
        int  N;
        cin >> N;
        while (N--)
        {
            for (int i = 1; i<=7;i++)
                cin >> s[i];
            cout <<get(0)<<get(5)<<":"<<get(12)<<get(17)<<endl;
        }
        return 0;
    }
    1011
  • 相关阅读:
    SQL语句 基本查询
    NHibernate 映射基础(第三篇) 简单映射、联合主键
    NHibernate 数据查询之Linto to NHibernate (第八篇)
    NHibernate 组件基础 (第六篇)
    SQL Server聚合函数
    NHibernate 集合映射深入 (第五篇) <set>,<list>,<map>,<bag>
    2020年10月笔记
    亚马逊云服务器aws配置ssl https证书
    namecheap mx记录配置邮箱
    为 PHPer 准备的 Go 入门知识
  • 原文地址:https://www.cnblogs.com/myhappinessisall/p/7281765.html
Copyright © 2011-2022 走看看