답안 #715704

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
715704 2023-03-27T14:46:57 Z hamidh100 Anagramistica (COCI21_anagramistica) C++17
110 / 110
19 ms 5648 KB
/* In the name of God */

#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <bitset>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <list>
#include <map>
#include <numeric>
#include <limits>
#include <limits.h>
#include <unordered_map>
#include <unordered_set>
#include <chrono>
#include <random>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef map<int, int> MPII;
typedef vector<int> VI;
typedef vector<ll> VL;
#define PB push_back
#define POP pop_back
#define MP make_pair
#define all(a) (a).begin(), (a).end()
#define endl '\n'
#define dbg(x) cerr << '[' << #x << ": " << x << "]\n"
#define dbg2(x, y) cerr << '[' << #x << ": " << x << ", " << #y << ": " << y << "]\n"
#define Yes cout << "Yes\n"
#define YES cout << "YES\n"
#define No cout << "No\n"
#define NO cout << "NO\n"

const ll INF = (ll)2e18 + 1386;
const ld eps = 0.000000000000001;
int MOD = 1e9 + 7;

inline int mod_(int a){ int res = a + MOD; return (res >= MOD? res - MOD : res); }
inline int mod_add(int a, int b){ int res = a + b; return (res >= MOD? res - MOD : res); }
inline int mod_neg(int a, int b){ int res = (abs(a - b) < MOD? a - b : (a - b) % MOD); return (res < 0? res + MOD : res); }
inline int mod_mlt(int a, int b){ return (1ll * a * b % MOD); }
inline string intToString(ll a){ char x[100]; sprintf(x, "%lld", a); string s = x; return s; }
inline ll stringToInt(string s){ ll res; char x[100]; strcpy(x, s.c_str()); sscanf(x, "%lld", &res); return res; }
inline void fileIO(string i, string o){ freopen(i.c_str(), "r", stdin); freopen(o.c_str(), "w", stdout); }

const int MAXN = 2001;

int dp[MAXN][MAXN], mods[] = {923232361, (int)1e9 + 9, 1000696969}, base = 9239;
ll fact[MAXN], inv[MAXN];
map<pair<int, PII>, int> cnt;
vector<pair<int, PII>> vec;

ll poww(ll x, int y, int p = MOD){
    ll res = 1;
    x %= p;
    while (y > 0){
        if (y & 1)
            res = (res * x) % p;
        y >>= 1;
        x = (x * x) % p;
    }
    return res;
}

void initFact(int _limit = MAXN){
    fact[0] = 1;
    for (int i = 1; i < _limit; i++){
        fact[i] = mod_mlt(fact[i - 1], i);
    }
}

void initInv(int _limit = MAXN){
    inv[_limit - 1] = poww(fact[_limit - 1], MOD - 2);
    for (int i = _limit - 2; i >= 0; i--){
        inv[i] = mod_mlt(inv[i + 1], i + 1);
    }
}

ll nCr(int n, int r){
    if (n < r) return 0;
    if (r == 0 || n == r) return 1;
    return (fact[n] * inv[r] % MOD * inv[n - r] % MOD) % MOD;
}

pair<int, PII> Hash(string s){
    int res[] = {0, 0, 0};
    for (int i = 0; i < 3; i++){
        MOD = mods[i];
        for (char ch : s){
            res[i] = mod_add(mod_mlt(res[i], base), ch - 'a' + 1);
        }
    }
    return MP(res[0], MP(res[1], res[2]));
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    initFact(), initInv();
    int n, k;
    cin >> n >> k;
    while (n--){
        string s; cin >> s;
        sort(all(s));
        auto x = Hash(s);
        vec.PB(x);
        cnt[x]++;
    }
    vec.PB(MP(0, MP(0, 0)));
    sort(all(vec));
    vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
    n = vec.size();
    dp[0][0] = 1;
    MOD = (int)1e9 + 7;
    for (int i = 1; i < n; i++){
        auto H = vec[i];
        int c = cnt[H];
        for (int j = 0; j <= k; j++){
            dp[i][j] = mod_mlt(dp[i - 1][j], c + 1);
            for (int k = 2; k <= c; k++){
                if (1ll * k * (k - 1) / 2 > j) break;
                dp[i][j] = mod_add(dp[i][j], mod_mlt(nCr(c, k), dp[i - 1][j - (k * (k - 1) / 2)]));
            }
        }
    }
    cout << dp[n - 1][k];
    return 0;
}

# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 596 KB Output is correct
2 Correct 2 ms 1620 KB Output is correct
3 Correct 1 ms 468 KB Output is correct
4 Correct 3 ms 1672 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 1 ms 340 KB Output is correct
5 Correct 1 ms 340 KB Output is correct
6 Correct 1 ms 596 KB Output is correct
7 Correct 2 ms 1620 KB Output is correct
8 Correct 1 ms 468 KB Output is correct
9 Correct 3 ms 1672 KB Output is correct
10 Correct 2 ms 1748 KB Output is correct
11 Correct 2 ms 468 KB Output is correct
12 Correct 1 ms 596 KB Output is correct
13 Correct 2 ms 468 KB Output is correct
14 Correct 4 ms 1236 KB Output is correct
15 Correct 2 ms 468 KB Output is correct
16 Correct 8 ms 5648 KB Output is correct
17 Correct 19 ms 572 KB Output is correct
18 Correct 2 ms 1364 KB Output is correct