zoukankan      html  css  js  c++  java
  • 少年,你渴望力量吗(20190831)?

    今日份考试,手动滑稽

     

    一、FFF团

    【题目描述】

    从前,Shylock和Lucar 幸福的生活在一起。

    在情人节前夕,他们出去逛街,遇到了FFF团的成员集体活动,于是他们就被FFF团抓进了地牢,并把他们关进了随机的两个不同的房间里。FFF团的团长打算明天将他们淹没在火海之中。但是团长给了他们一个机会,如果他们其中一个人能到达另一个人的房间(另一个人不动),那么就放过他们,否则就关到第二天然后点火。

    地牢里面有n个房间,m条路,每一条路连接两个房间,并且路是有方向的。

    现在问Shylock和Lucar是否无论在任何情况下,都满足他们其中一个人能到达另一个人的房间,如果是则输出“I love you my love and our love save us!”,否则输出“Light my fire!”

    【输入格式】

    本题包含多组数据。

    对于每组数据,第一行输入T,表示数据组数。

    下面一行两个整数n,m,分别表示房间数和路的数量。

    接下来的m行,每行两个整数x,y,表示从第x个房间有一条路可以到达y房间。

    每组数据后有一个空行。

    【输出格式】

    输出一行,如果问Shylock和Lucar是否无论在任何情况下,都满足他们其中一个人能到达另一个人的房间,如果是则输出“I love you my love and our love save us!”,否则输出“Light my fire!”


    一波强连通缩点,再来个拓扑排序

    非常美妙,令人极度舒适

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    const int maxn=20005,maxm=200005;
    int T,n,m,k,hd[maxn],dfn[maxn],low[maxn],belong[maxn];
    int tot,col,fr[maxn],to[maxn],fa[maxn],d[maxn];
    struct node{
        int fr,to,nt;
    }e[maxm];
    
    inline void add(int x,int y)
    {
        e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].fr=x;
    }
    
    stack<int>s;
    
    inline void tarjan(int x)
    {
        s.push(x);
        dfn[x]=low[x]=++tot;
        for(int i=hd[x];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if(!belong[v])
                low[x]=min(low[x],dfn[v]);
        }
        
        if(dfn[x]==low[x])
        {
            ++col;
            int v=-1;
            while(v!=x)
            {
                v=s.top();
                s.pop();
                belong[v]=col;
            }
        }
    }
    
    inline int find(int x)
    {
        re x==fa[x]?x:fa[x]=find(fa[x]);
    }
    
    inline bool topo()
    {
        int cnt=0;
        k=0;
        inc(i,1,col)hd[i]=0;
            
        inc(i,1,m)
        {
            int x=belong[e[i].fr];
            int y=belong[e[i].to];
            if(x!=y)
            {
                add(x,y);
                ++d[y];
            }
        }
        
        queue<int>q;    
        inc(i,1,col)if(!d[i])
        {
            ++cnt;
            q.push(i);
        }
        
        while(!q.empty())
        {
            if(cnt>1)re 1;
            int u=q.front();
            --cnt;
            q.pop();
            for(int i=hd[u];i;i=e[i].nt)
            {
                int v=e[i].to;
                --d[v];
                if(!d[v])
                {
                    ++cnt;
                    q.push(v);
                }
            }
        }
        re 0;    
    }
    
    int main()
    {
        
        //freopen("in.txt","r",stdin);
        rd(T);
        while(T--)
        {
            rd(n),rd(m);
            k=tot=col=0;
            inc(i,1,n)
            {
                dfn[i]=low[i]=belong[i]=0;
                d[i]=to[i]=fr[i]=hd[i]=0;
                fa[i]=i;    
            }
            
            int x,y;
            inc(i,1,m)
            {
                rd(x),rd(y);
                add(x,y);
            }
            
            
            inc(i,1,n)
            if(!dfn[i])
                tarjan(i);
            
            
            if(topo())printf("Light my fire!
    ");
            else printf("I love you my love and our love save us!
    ");
        }
        re 0;
    } 

    二、maple做数学题

    【题目描述】

    有一天,maple上数学课,他学会了如何求一个数的因子,于是老师给他布置了一道题,在区间[L,R]里面,找出所有满足下列条件的数字:这个数的第二小的因子为K。找到这些数字以后,maple还要去把这些数加起来,请问最终结果是什么?

    【输入格式】

    输入数据只有一行,三个数字L,R,K含义如题目描述所示

    【输出格式】

    一个整数,表示把这些数加起来的和是多少,答案模 mod1e9+7 mod1e9+7

    【输入样例1】

    1 20 5

    【输出样例1】

    5

    【输入样例2】

    2 6 3

    【输出样例2】

    3

    【数据约定】

    20%的数据1LR10^5 ,2K10^5 1≤L≤R≤10^5,2≤K≤10^5

    100%的数据1LR10^11 ,2K10^11 1≤L≤R≤10^11,2≤K≤10^11


    像我这样的数学渣:

    咦,数学诶!

    思考1min……

    不可做,绝对不可做

    看了看第三题,又是一道古拉拉级膜法题:数学

    暴力,暴力~~~

    爆零,爆零~~~

    然而坚强的LL成功苟到60pts(鲜花,掌声)

    正解(dp)

    #include<bits/stdc++.h>
    #define re return
    #define ll long long
    #define inc(i,l,r) for(int i=l;i<=r;++i)
    
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    const int maxn=16000005,NN=10010,MM=120;
    const ll mod=1e9+7;
    
    ll L,R,K,dp[NN][MM];
    ll cnt,notprime[320005],prime[320005];
    
    inline bool isprime(ll x)
    {
        if(x%2==0&&x!=2)re 0;
        for(int i=3;i<=sqrt(x);i+=2)
        if(!(x%i))re 0;
        re 1;
    }
    
    inline void Get_prime()//得到质数 
    {
        notprime[1]=1;
        inc(i,2,K)
        {
            if(!notprime[i])
            prime[++cnt]=i;
            
            inc(j,1,cnt)
            {
                if(prime[j]*i>K)break;
                notprime[prime[j]*i]=prime[j];
                if(!(i%prime[j]))break;
            }
        }
    }
    
    
    inline ll F(ll n,ll m)
    //F(n,m)表示前i个数,去掉前m个质数的和 
    {
        ll ans;
        if(n<NN&&m<MM&&dp[n][m])re dp[n][m];//记忆化 
        else if(n<2)ans=n;//0,1不是任何质数的正整数级倍数 
        else if(!m) ans=((1+n)%mod)*(n%mod)%mod*500000004%mod;
        //即求前n个数的和,等差数列
        //因为除法取模不成立,所以转化为乘其(2)逆元(500000004) 
        else if(prime[m]>n)
        {
            while(m&&prime[m]>n)--m;
            //prime[m]>n无意义
            //简化 
            ans=F(n,m);
        }
        else ans=(F(n,m-1)-prime[m]*F(n/prime[m],m-1)%mod+mod)%mod;
        //重点 :对于(n/prime[m]),比如说5,5的2倍,以及5的3倍都是不成立的 
        if(n<NN&&m<MM)dp[n][m]=ans;//记忆化 
        re ans;
    }
    
    int main()
    {
        rd(L),rd(R),rd(K);
        
        if(!isprime(K))printf("0");
        //如果K不是素数,则其倍数次小因子绝对不是K 
        else if(sqrt(R)<K)
        {
        //当K在1~R中最多只能苟一个即(K)时 
            if(R>=K&&K>=L)printf("%lld",K%mod);
            else printf("0");
        }
        else 
        {
            Get_prime();//得到小于K的所有质数 
            printf("%lld",(F(R/K,cnt-1)*K%mod-F((L-1)/K,cnt-1)*K%mod+mod)%mod);
        }
    
        re 0;
    } 

    三、数字

    【题目描述】

    有一个n个数字的列表,你可以对列表进行两种操作

    1.用x的代价删除一个数字

    2.用y的代价选择一个数字增加1

    两种操作没有次数限制,问使得这个列表所有数字的gcd(最大公因数)大于1的最少花费是多少?

    【输入格式】

    第一行三个整数表示n、x、y。

    第二行有n个整数表示这个列表的数字。

    【输出格式】

    一个整数表示最少花费。

    【输入样例1】

    4 23 17
    1 17 17 16

    【输出样例1】

    40

    【输入样例2】

    10 6 2
    100 49 71 73 66 96 8 60 41 63

    【输出样例2】

    10

    【数据约定】

    对于30%数据 1<=n<=1000

    对于100%数据 1<=n<=500000 ,1<=x,y<=1000000000, 1<=a[i]<=1000000


    突然明白为什么今天早上我错了……

    其实由于数据过水,gcd只用枚举50以内

    悲伤,雨中肖邦

    骗分大法

    #include<bits/stdc++.h>
    #define re return
    #define ll long long
    #define inc(i,l,r) for(register int i=l;i<=r;++i)
    
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    int prime[100005],notprime[1000005];
    int n,maxx,cnt,a[500005];
    
    inline void Get_prime()
    {
        notprime[1]=1;
        inc(i,2,50)
        {
            if(!notprime[i])
            prime[++cnt]=i;
            inc(j,1,cnt)
            {
                if(prime[j]*i>50)break;
                notprime[prime[j]*i]=prime[j];
                if(i%prime[j])break;
            }
        }
    }
    
    int main()
    {
        int cx,cy;
        rd(n),rd(cx),rd(cy);
        
        inc(i,1,n)
        {
            rd(a[i]);
            maxx=a[i]>maxx?a[i]:maxx;
        }
        
        ll ans=99999999999999999;
        Get_prime();//获得50以内的质因数
        inc(c,1,15)//共有16个
        {
            int i=prime[c];
            ll nowans=0;
            inc(j,1,n)
            {
                ll t=a[j]%i;
                    if(t)t=(i-t)*(ll)cy;//要成为i的倍数至少还要i-t;
                            //需要cy*(i-t)费用
                    nowans+=cx<t?cx:t;//比较取最小
                if(nowans>ans)break;//剪枝
            }
            ans=ans<nowans?ans:nowans;
        }
        //暴力枚举
        printf("%lld",ans); 
        re 0;
    } 
        
  • 相关阅读:
    view 与layer
    xcode中create groups 和 create folder reference 的区别
    iOS 9 学习系列:UIStack View (转载)
    使用JQuery插件,排序Gridview的某个字段
    Fixed GridView Header
    在TextBox里面仅仅允许数字,按Enter键进入下一个TextBox
    实现AJAX局部刷新以及PageMethod方法的使用
    用户控件
    JSON的使用
    ASP.NET页面生命周期
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11440362.html
Copyright © 2011-2022 走看看