話題ソリューション@ - 2020.03 @

GUGU区。

これらのトピックは、必ずしも私が行う前に、書かれていた私が今しなければならなかった問題への解決策があるかもしれない月ではないかもしれません。

トップコーダー- SRM545D1L3:全ビットが1である場合を除きビット単位の考慮、さもなければ両側はそれぞれ、少なくとも1つのゼロを有していなければなりません。ビット1および除外は、互いに素な集合演算結果を用いて、完全な側面です。

#include <cstdio>
#include <vector>
using namespace std;

typedef long long ll;

class SetAndSet{
    public:
        int a[20][50], cnt[20], fa[20][50];
        int find(int t, int x) {return fa[t][x] = (fa[t][x] == x ? x : find(t, fa[t][x]));}
        bool unite(int t, int x, int y) {
            int fx = find(t, x), fy = find(t, y);
            if( fx != fy ) {
                fa[t][fx] = fy;
                return true;
            }
            else return false;
        }
        ll ans; int n;
        void dfs(int d, int k, int f) {
            if( d == 20 ) {
                ans += f*((1LL << k) - 2);
                return ;
            }
            if( d )
                for(int i=0;i<n;i++) fa[d][i] = fa[d-1][i];
            else for(int i=0;i<n;i++) fa[d][i] = i;
            dfs(d + 1, k, f);
            if( cnt[d] ) {
                for(int i=1;i<cnt[d];i++)
                    if( unite(d, a[d][0], a[d][i]) ) k--;
                dfs(d + 1, k, -f);
            }
        }
        ll countandset(vector<int>A) {
            n = A.size();
            for(int i=0;i<20;i++) {
                cnt[i] = 0;
                for(int j=0;j<n;j++)
                    if( !((A[j] >> i) & 1) ) a[i][cnt[i]++] = j;
            }
            dfs(0, n, 1);
            return ans;
        }
};

ZOJ - 4064:包含と除外を考慮し、列挙はチェック柄のカバーを禁止しました。貢献しただけで、隣接するグリッドをカバーしていないので、[i] [j]は転送が何気なく行う、係数* jはカバレッジの範囲を含める排除プログラムの数を選択することができます持って、私をカバー禁止などの最新の位置を示しているDP覚えています。この質問は、多くの場合、カードを持っています。

#include <cstdio>

const int MAXN = 100;
const int MOD = int(1E9) + 7;

inline int add(int x, int y) {return (x + y >= MOD ? x + y - MOD : x + y);}
inline int sub(int x, int y) {return (x - y < 0 ? x - y + MOD : x - y);}
inline int mul(int x, int y) {return 1LL * x * y % MOD;}

int pow_mod(int b, int p) {
    int ret = 1;
    for(int i=p;i;i>>=1,b=mul(b,b))
        if( i & 1 ) ret = mul(ret, b);
    return ret;
}

int f[MAXN + 5][MAXN*MAXN + 5], A[MAXN + 5], n, m;

void solve() {
    scanf("%d%d", &n, &m);
    for(int i=1;i<=n;i++)
        scanf("%d", &A[i]);
    A[n + 1] = f[0][0] = 1;
    for(int i=0;i<=n;i++) {
        int t = i*(i + 1)/2;
        for(int j=0;j<=t;j++) {
            if( f[i][j] ) {
                for(int k=i+1;k<=n+1;k++) {
                    if( A[k] == 1 ) {
                        f[k][j+(k-i)*(k-i-1)/2] = add(f[k][j+(k-i)*(k-i-1)/2], f[i][j]);
                        break;
                    }
                    else if( A[k] == 2 )
                        f[k][j+(k-i)*(k-i-1)/2] = sub(f[k][j+(k-i)*(k-i-1)/2], f[i][j]);
                }
            }
        }
    }
    int ans = 0, t = n*(n + 1)/2;
    for(int i=0;i<=t;i++)
        ans = add(ans, mul(f[n+1][i], pow_mod(i, m)));
    for(int j=0;j<=n+1;j++)
        for(int k=0;k<=t;k++)
            f[j][k] = 0;
    printf("%d\n", ans);
}

int main() {
    int T; scanf("%d", &T);
    while( T-- ) solve();
}

おすすめ

転載: www.cnblogs.com/Tiw-Air-OAO/p/12409459.html