紫书第10章存题

UVA 580 枚举出现连续3个U第一次出现的位置。同时需要记录前i位不出现连续3个u的方案。

#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 20 + 10;
ll f[maxn],g[maxn];
ll quick(ll a,int n)
{
    ll res = 1;
    while(n) {
        if(n&1) res *= a;
        a *= a;
        n >>= 1;
    }
    return res;
}
void init(int n)
{
    f[0] = f[1] = f[2] = 0;
    g[0] = 1;g[1] = 2;g[2] = 4;
    for(int i = 3; i <= n; ++i) {
        f[i] = quick(2,i-3);
        for(int j = 2; j <= i-2; ++j) {
            f[i] += g[j-2]*quick(2,i-j-2);
        }
        g[i] = quick(2,i) - f[i];
    }
}
int main(int argc, char const *argv[])
{
    init(30);
    int n;
    while(~scanf("%d",&n)&&n) {
        printf("%lld\n", f[n]);
    }
    return 0;
}


UVA 12034 n人比赛,最终名次方案数,枚举第一名并列人数,缩小规模。

#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 10;
int c[maxn][maxn],res[maxn];
const int mod = 10056;
void init(int n)
{
    for(int i = 0; i <= n; ++i) {
        c[i][0] = 1;
        for(int j = 1; j <= i; ++j)
            c[i][j] = (c[i-1][j-1] + c[i-1][j])%mod;
        c[i][i+1] = 0;
    }
    res[0] = 1;
    for(int i = 1; i <= n; i++) {
        res[i] = 0;
        for(int j = 1; j <= i; j++)
            res[i] = (res[i] + c[i][j]*res[i-j])%mod;
    }
}
int main(int argc, char const *argv[])
{
    init(1000);
    int T; scanf("%d",&T);
    for(int cas = 1,n; cas <= T; ++cas) {
        scanf("%d",&n);
        printf("Case %d: %d\n", cas, res[n]);
    }
    return 0;
}

UVA 1639 注意用long doule提高精度


#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
const int maxn = 5e3 + 10;
typedef long long ll;
int main()
{
    int n; long double p;
    int cas = 1;
    while(cin>>n>>p) {
        if(p==1.0||p==0.0) {
            printf("Case %d: %.6f\n",cas++,1.0*n);
            continue;
        }
        long double res = 0;
        long double t = 0;
        for(int i = 1; i <= n; i++) t += log(2*n-i+1.0)-log(n-i+1.0);
        int dy = 2*n,dx = n;
        for(int i = 1; i <= n; i++) {
            t += log(dx--) - log(dy--);
            double v1 = t + (n+1)*log(p)+(n-i)*log(1-p);
            double v2 = t + (n+1)*log(1.0-p)+(n-i)*log(p);
            res += i*(exp(v1)+exp(v2));
        }
        printf("Case %d: %.6f\n",cas++,(double)res);
    }
    return 0;
}


UVA11440欧拉函数,需要求n!的欧拉函数值,递推求

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define pb push_back
const int maxn = 10000000 + 10;
typedef long long ll;
const ll mod = 100000007;
int phifac[maxn];
bool vis[maxn];
void init(int n)
{
    memset(vis,0,sizeof vis);
    for(ll i = 2; i <= n; i++) if(!vis[i]) {
        for(ll j = i*i; j <= n; j += i) vis[j] = 1;
    }
    phifac[1] = 1;
    for(int i = 2; i <= n; i++)
        phifac[i] = (ll)phifac[i-1]*(vis[i]?i:i-1)%mod;
}
int gao(int n,int m)
{
    int res = phifac[m];
    for(ll i = m+1; i <= n; i++) res = ((ll)res*i)%mod;
    return (res-1+mod)%mod;
}
int main (){
    int n,m;
    init(maxn-10);
    while(~scanf("%d%d",&n,&m)&&(n+m)) {
        printf("%d\n",gao(n,m));
    }
    return 0;
}

UVA 10214欧拉函数应用需要注意gcd(x+i,x) = gcd(x,i)

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 2000 + 10;
typedef long long ll;
const ll mod = 100000007;
int phi[maxn];
void init(int n)
{
    memset(phi,0,sizeof phi);
    phi[1] = 1;
    for(int i = 2; i <= n; i++)if(!phi[i]){
        for(int j = i; j <= n; j+=i) {
            if(!phi[j])phi[j] = j;
            phi[j] = phi[j]/i*(i-1);
        }
    }
}
int gcd(int a,int b) {
    while(a&&b) {
        if(a>b)a%=b;
        else b%=a;
    }
    return a + b;
}
double gao(int a,int b)
{
    long double res = 0;
    if(a>b)swap(a,b);
    for(int x = 1; x <= a; x++) {
        ll t = b/x;
        res += phi[x]*t;
        for(int y = t*x+1; y <= b; y++)if(gcd(x,y)==1) {
            res = res + 1;
        }
    }
    ll t = (2.0*a+1)*(2.0*b+1)-1;
    return (4.0+4.0*res)/t;
}
int main (){
    int n,m;
    init(maxn-10);
    while(~scanf("%d%d",&n,&m)&&n&&m) {
        printf("%.7lf\n",gao(n,m));
    }
    return 0;
}


UVA 1642 动态维护gcd值左端点,gcd值只有logn 个,可以直接暴力维护去重

#include <bits/stdc++.h>
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
using namespace std;
typedef long long ll;
int main()
{
    int T;scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d",&n);
        vector<ll>gcd;
        ll ans = 0;
        vector<int>L;
        for(int i = 1; i <= n; i++) {
            ll x;scanf("%lld",&x);
            ans = max(ans,x);
            bool found = 0;
            for(int j = 0; j < gcd.size(); j++) {
                gcd[j] = __gcd(gcd[j],x);
                if(gcd[j]==x)found = true;
                ans = max(gcd[j]*(i-L[j]+1),ans);
            }
            if(!found) {
                gcd.push_back(x);
                L.push_back(i);
            }
            vector<pair<ll,int> >t;
            for(int i = 0; i < gcd.size(); i++) {
                bool ok = false;
                for(int j = 0; j < t.size(); j++) {
                    if(gcd[i]==t[j].first) {
                        ok = true;
                        t[j].second = min(t[j].second,L[i]);
                        break;
                    }
                }
                if(!ok)t.push_back(make_pair(gcd[i],L[i]));
            }
            gcd.resize(t.size());
            L.resize(t.size());
            for(int j = 0; j < t.size(); ++j){
                gcd[j] = t[j].first;
                L[j] = t[j].second;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值