• ZOJ Monthly, August 2009 总结


    C.Lucky Number

      容斥原理,刚开始一直苦于想不出后面 NBUN个数至少有一个不能整除怎么保证...后来还是ry提醒才想到,居然可以反过来想,假设这 NBUN个元素分别为a1,a2....a NBUN  ,也就是只要不能整除Temp=lcm(a1,a2....a NBUN)就行了,然后对于剩下的NBLN个只要有一个可以整除就合法的元素直接容斥就可以了,在过程中要保证每次减掉能整除Temp的情况就编程裸容斥了,注意lcm可能爆long long,要特殊处理!!一直调到最后才AC,真心坑队友啊ToT..

    ZOJ 3233
    #include <iostream>
    #include <cstdio>
    #define INF 1000000000000000000LL
    using namespace std;
    int va[20],n;//n为不能整除的数
    long long no,ans;
    
    long long gcd(long long x,long long y){
        while(x){
            long long temp=x;
            x=y%x;
            y=temp;
        }
        return y;
    }
    
    long long lcm(long long x,long long y){
        return x/gcd(x,y)*y;
    }
    
    void dfs(int st,int cnt,long long now,long long x){    //下一个因子起始位置,当前因子数,当前和因子值,结尾数字
        if(cnt>=1){
            if(cnt&1){
                long long dis;
                if(no>x) dis=0;
                else dis=x/lcm(now,no);
                long long temp=x/now-dis;
                ans+=temp;
            }
            else{
                long long dis;
                if(no>x) dis=0;
                else dis=x/lcm(now,no);
                long long temp=x/now-dis;
                ans-=temp;
            }
        }
        for(int i=st;i<n;i++)
            dfs(i+1,cnt+1,va[i]/gcd(now,va[i])*now,x);
    }
    long long solve(long long x){
        ans=0;
        dfs(0,0,1,x);
        return ans;
    }
    
    int main()
    {
        int m,i,j;
        long long st,end,a;
        while(scanf("%d%d%lld%lld",&n,&m,&st,&end)!=EOF){
            if(n==0&&m==0&&st==0&&end==0)
                break;
            for(i=0;i<n;i++)
                scanf("%d",&va[i]);
            no=1;
            for(i=0;i<m;i++){
                scanf("%lld",&a);
                no=lcm(a,no);
                if(no>INF){    //防溢出
                    for(j=i+1;j<m;j++)
                        scanf("%lld",&a);
                    no=end+1;
                    break;
                }
            }
            printf("%lld\n",solve(end)-solve(st-1));
        }
        return 0;
    }

     E.Prototype

      简单推方程式,由题目给定的条件可以求出中间转折点的X坐标的方程,-(a+b)x02+2*b*d2*x0+h1=0,然后分别判定两个解是否满足题目的条件即可,注意,题目第一段有说到,在转折点不能往回跳!!这个地方被坑死了!

    ZOJ 3235
    #include<stdio.h>
    #include<math.h>
    double h1,h2,d1,d2,a,b;
    bool check(double x)
    {
        if(x<0||x>d2) return 0;
        if(x>d1){
            if(h1-a*d1*d1>=h2) return 1;
            else return 0;
        }
        if(x<d1){
            double y=-a*x*x+h1;
            double y2=-b*(d1-x)*(d1-x)+y;
            if(y2>=h2) return 1;
            else return 0;
        }
    }
    
    int main()
    {
        while(scanf("%lf%lf%lf%lf%lf%lf",&h1,&h2,&d1,&d2,&a,&b)!=EOF)
        {
            double A=-(a+b);
            double B=2*b*d2;
            double C=h1-b*d2*d2;
            double drt=B*B-4*A*C;
            if(drt<0){
                printf("No\n");    continue;
            }
            drt=sqrt(drt);
            double x1=(-B-drt)/2/A,x2=(-B+drt)/2/A;
            if(check(x1))
                printf("Yes\n");
            else if(check(x2))
                printf("Yes\n");
            else
                printf("No\n");
        }
        return 0;
    }

    G.Signals and Systems

      应该算是数论吧...真心弱爆了,每次赛后才会做又有什么用呢ToT,给出出现极值的n-1个坐标,也就是f(t)的导数f'(t)=0有n-1个解,我们可以表示成这样的形式:

      f'(t)=(t-t1)*(t-t2)*...*(t-tn-1)

      可以看出tn-1的系数一定是1,又因为f(t)里tn的系数是an,可以得到an*n=1,根据要求 an * n = 1,正好系数就是1/n

      同样的,其它f(t)的项ti的系数也是f'(t)的ti-1项的系数除以i

      还有一点就是系数可能爆longlong,这里直接对lcm(1,2,3,....32)取模即可

    ZOJ 3237
    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define MOD 144403552893600LL
    long long va[40];
    long long dp[36][36];
    int get(long long x,long long div){
        x=(x%MOD+MOD)%MOD;
        if(x%div==0) return 0;
        x=x%div;
        while(x<div) x*=10;
        return x/div;
    }
    
    int main()
    {
        int T,n,i,j;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            for(i=1;i<n;i++)
                scanf("%lld",&va[i]);
            dp[0][0]=1;
            for(i=1;i<n;i++){
                dp[i][0]=(dp[i-1][0]*va[i])%MOD;
                for(j=1;j<=i;j++)
                    dp[i][j]=(dp[i-1][j-1]+dp[i-1][j]*va[i])%MOD;
            }
            printf("0");
            for(i=1;i<n;i++)
                printf(" %d",get(dp[n-1][i],i+1));
            printf("\n");
        }
        return 0;
    }
  • 相关阅读:
    【hdu2825-Wireless Password】AC自动机+DP
    kuangbin专题十二 HDU1029 Ignatius and the Princess IV (水题)
    Codeforces Round #501 (Div. 3) 1015D Walking Between Houses
    Codeforces Round #501 (Div. 3) 1015A Points in Segments (前缀和)
    POJ2503 Babelfish
    POJ2531 Network Saboteur
    POJ3278 Catch That Cow
    POJ2488 A Knight's Journey
    POJ2456 Aggressive cows
    HDU1425 A Chess Game
  • 原文地址:https://www.cnblogs.com/SolarWings/p/3052360.html
Copyright © 2020-2023  润新知