zoukankan      html  css  js  c++  java
  • 2019杭电多校训练(四)

    比赛链接:

    http://acm.hdu.edu.cn/search.php?field=problem&key=2019+Multi-University+Training+Contest+4&source=1&searchmode=source

    hdu6623

    题意:

    把一个数转化成质因数加指数连乘的形式,求最小指数

    分析:

    当时我们考虑先筛出$1e18^{frac{1}{4}}$的所有素数,复杂度大概在$2e8$左右,刚好被卡了

    其实筛到$1e18^{frac{1}{5}}$的情况也不是很复杂(当时以为四个因数太复杂了,没敢写)

    把小于$1e18^{frac{1}{5}}$的质因子去掉,剩下的最多有四个质因子

    如果M可以开四次根,那么M一定是qqqq的形式

    如果M可以开三次根,那么M一定是qqq的形式

    如果M可以开二次根,那么M一定是qq或者qqpp形式

    否则M一定存在一次幂

    ac代码:

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 1e6 + 5;
    const ll mod = 1e9 + 7;
    int vis[maxn],prim[maxn],top;
    bool check(ll x,int y)//判断x能否开y次幂
    {
    
        ll st=1,en=pow(1e18,1.0/y)+1;
        while(st!=en){
            ll md=(st+en)/2;
            ll res=1;
            for(int i=1;i<=y;i++)res*=md;
            if(res>=x)en=md;
            else st=md+1;
        }
        ll res=1;
        for(int i=1;i<=y;i++)res*=st;
        if(res==x)return 1;
        else return 0;
    }
    
    int main()
    {
       // cout<<check(8,3)<<endl;
        for(int i=2;i<=4000;i++){
            if(vis[i]==0){
                prim[++top]=i;
                //cout<<i<<endl;
                for(int j=2*i;j<=4000;j+=i)
                    vis[j]=1;
            }
        }
        int T;
        scanf("%d",&T);
        while(T--){
            int ans=70;
            ll n;
            scanf("%lld",&n);
            for(int i=1;i<=top;i++){
                if(n%prim[i]==0){
                    int res=0;
                    while(n%prim[i]==0)n/=prim[i],res++;
                    ans=min(res,ans);
                    if(ans==1)break;
                }
            }
            if(n==1||ans==1){
                printf("%d
    ",ans);
                continue;
            }
            if(check(n,4))ans=min(ans,4);
            else if(check(n,3))ans=min(ans,3);
            else if(check(n,2))ans=min(ans,2);
            else ans=1;
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    hdu6621

    题意:

    给出$n$个数,和$m$次询问

    每次询问是一段区间中,所有数与$p$的差值的第$k$大

    分析:

    二分答案再主席树验证

    现在才真正理解主席树的含义,就是保存了$n$棵区间和的线段树

    既可以求第$k$大也可以求出某段区间数的数量

    ac代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn=1e5+5;
    struct Tree
    {
         int L,R,num;
    }tree[maxn*25];
    int root[maxn];
    int cnt;
    void updata(int x,int &rt,int a,int b)
    {
         tree[cnt++]=tree[rt];
         rt=cnt-1;
         tree[rt].num++;
         if(a==b)return;
         int mid=(a+b)/2;
         if(x>=mid+1)
             updata(x,tree[rt].R,mid+1,b);
         else
             updata(x,tree[rt].L,a,mid);
    }
    int quer(int l,int r,int a,int b,int st,int en)//quer(root[l-1],root[r],r-l+1-mid,1,n)
    {
        if(a>en||b<st)return 0;
        if(a<=st&&b>=en)return tree[r].num-tree[l].num;
        int md=(st+en)/2;
        return quer(tree[l].L,tree[r].L,a,b,st,md)+quer(tree[l].R,tree[r].R,a,b,md+1,en);
    }
    int main()
    {
        int n,m,T;
        scanf("%d",&T);
        while(T--)
        {
            for(int i=0;i<maxn*25;i++)tree[i].num=0;
            scanf("%d %d",&n,&m);
            cnt=1;
            for(int i=1;i<=n;i++)
            {
                root[i]=root[i-1];
                int x;
                scanf("%d",&x);
                updata(x,root[i],1,1e6);
            }
    //        cout<<quer(root[1],r,1,1,1,1e6)<<endl;
            int ans=0;
            for(int i=1;i<=m;i++)
            {
                int l,r,p,k;
                scanf("%d %d %d %d",&l,&r,&p,&k);
                l^=ans,r^=ans,p^=ans,k^=ans;
                int st=0,en=1e6;
                while(st!=en){
                    int md=(st+en)/2;
                    if(quer(root[l-1],root[r],max(1,p-md),min(1000000,md+p),1,1e6)>=k)en=md;
                    else st=md+1;
                }
                ans=st;
                printf("%d
    ",st);
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    POJ 3660 Cow Contest (floyd求联通关系)
    POJ 3660 Cow Contest (最短路dijkstra)
    POJ 1860 Currency Exchange (bellman-ford判负环)
    POJ 3268 Silver Cow Party (最短路dijkstra)
    POJ 1679 The Unique MST (最小生成树)
    POJ 3026 Borg Maze (最小生成树)
    HDU 4891 The Great Pan (模拟)
    HDU 4950 Monster (水题)
    URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
    URAL 2037 Richness of binary words (回文子串,找规律)
  • 原文地址:https://www.cnblogs.com/carcar/p/11290006.html
Copyright © 2011-2022 走看看