North American Invitational Programming Contest (NAIPC) 2016

(待补)

A. Fancy Antiques

爆搜。

B. Alternative Bracket Notation

C. Greetings!

D. Programming Team

0/1分数规划 + 树上依赖型背包。

E. K-Inversions

将 A 和 B 的相对位置看做多项式,用FFT,最后统计系数。

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);

struct comp{
    double r,i;
    comp(double _r=0, double _i=0):r(_r),i(_i) {}
    comp operator + (const comp& x) { return comp(r+x.r, i+x.i); }
    comp operator - (const comp& x) { return comp(r-x.r, i-x.i); }
    comp operator * (const comp& x) { return comp(r*x.r-i*x.i, r*x.i+i*x.r); }
};

void FFT(comp a[], int n, int t)
{
    for(int i=1, j=0; i < n-1; i++)
    {
        for(int s=n; j^=s>>=1, ~j&s;);
        if(i<j)
            swap(a[i],a[j]);
    }
    for(int d=0; (1<<d)<n; d++)
    {
        int m=1<<d, m2=m<<1;
        double o=pi/m*t;
        comp _w(cos(o),sin(o));
        for(int i=0; i<n; i+=m2)
        {
            comp w(1,0);
            for(int j=0; j<m; j++)
            {
                comp& A=a[i+j+m], &B=a[i+j], t=w*A;
                A=B-t;
                B=B+t;
                w=w*_w;
            }
        }
    }
    if(t == -1)
        for(int i=0; i<n; i++)
            a[i].r=floor(a[i].r/n+0.5);
}

const int maxn = 3e6 + 100;
comp A[maxn], B[maxn];
char str[maxn];
int len;

int main()
{
    scanf("%s", str);
    len = strlen(str);
    for(int i = 0; i < len; ++i)
    {
        if(str[i] == 'B')
            A[i].r=0, B[len-i].r=1;
        else
            A[i].r=1, B[len-i].r=0;
    }
    int tmp = 1;
    while(tmp < 2*len)
        tmp*=2;
    swap(len, tmp);
    FFT(A, len, 1);
    FFT(B, len, 1);
    for(int i = 0; i < len; ++i)
        A[i] = A[i]*B[i];
    FFT(A, len, -1);
    for(int i = tmp+1; i < 2*tmp; ++i)
    {
        printf("%.0f
", A[i].r);
    }

    return 0;
}

  

F. Mountain Scenes

dp[i][j]表示前 i 块区域总共用的长度为 j

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100 + 100;
const int MOD = 1e9 + 7;
int dp[maxn][10010];

int main()
{
    int n, w, h;
    scanf("%d%d%d", &n, &w, &h);
    dp[0][0] = 1;

    for (int i = 1; i <= w; i++)
    for (int j = 0; j <= n; j++)
        for (int k = 0; k <= h; k++)
        {
            if (j+k > n) break;
            dp[i][j+k] += dp[i-1][j];
            if (dp[i][j+k] >= MOD) dp[i][j+k] -= MOD;
        }

    LL ans = 0;
    for (int i = 1; i <= n; i++) ans += dp[w][i];
    for (int i = 1; i <= h; i++)
        if (i * w <= n) ans--;
    printf("%lld
", (ans+MOD) % MOD);
}

  

G. Symmetry

H. Jewel Thief

 

 

I. Tourists

LCA爆。复杂度O(nlog2n)。 

J. Whiteboard

 

 

 

K. YATP

原文地址:https://www.cnblogs.com/ruthank/p/9737664.html