Warning: mysqli_query(): (HY000/1021): Disk full (/tmp/#sql_51b_2.MAI); waiting for someone to free some space... (errno: 28 "No space left on device") in /opt/lampp/htdocs/wordpress/wp-includes/wp-db.php on line 2033
AtCoder Beginner Contest 152()-其他 – 知识波

# AtCoder Beginner Contest 152()-其他

## AtCoder Beginner Contest 152()

### AtCoder Beginner Contest 152

https://atcoder.jp/contests/abc152
F我看了半天，编码方式那里还算是感觉比较玄乎，这题确实妙。

### D – Handstand 2

``````#include <bits/stdc++.h>
#define ll long long

using namespace std;
ll n, sum, a[10][10];
ll pw[] = {1, 10, 100, 1000, 10000, 100000, 1000000};

int main () {
cin >> n;
for (int i = 1; i <= n; i++)    a[i / pw[(int)to_string (i).size () - 1]][i % 10] ++;
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
sum += a[i][j] * a[j][i];
}
}
cout << sum;
}

//只存首尾
``````

### E – Flatten

``````#include <bits/stdc++.h>
#define ll long long

using namespace std;
typedef pair<int, int> pii;
const int N = 1e4 + 5, mod = 1e9 + 7, M = 1e6 + 5;// M = 78499 + 5; //1e6以内素数的个数
int n, a[N], cnt[M];
ll sum;

ll qmi(ll a, ll k, ll p){
ll res = 1;
while(k){
if(k & 1)
res = (ll)res * a % p;
a = (ll)a * a % p;
k >>= 1;
}
return res;
}

int main () {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
// cout << a[i] << ":\n";
int t = a[i];
for (int j = 2; j * j <= t; j++) {
if (t % j == 0) {
int tt = 0;
while (t % j == 0)    t /= j, tt++;
cnt[j] = max (tt, cnt[j]);
}
}
if (t > 1)   cnt[t] = max (cnt[t], 1);
}

ll mul = 1;
for (int i = 1; i < M; i++) {
while (cnt[i]--)    (mul *= i) %= mod;
}
for (int i = 1; i <= n; i++)    (sum += mul % mod * qmi (a[i], mod - 2, mod)) %= mod;
cout << sum;
}

//d/ai求和
//对ai进行素因数分解
``````

### F – Tree and Constraints

https://www.luogu.com.cn/blog/subtlemaple/solution-at-abc152-f

``````#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 55;
int h[N], e[N*2], ne[N*2], idx;
ll n, m, d[N], st[N]; //di为限制条件, st[i]当前边状态

void add (int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void dfs (int u, int fa) {
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (j == fa)    continue;
d[j] = d[u] | (1ll << (j - 1)); //根节点到 x 经过的边的状压数值
dfs (j, u);
}
}

ll count (ll S) { //f(S) = 2^{n-1-|S|}
ll cnt = __builtin_popcountll (S), T = 0; //T为并集
for (int i = 0; i < m; i++) {
if (S & (1ll << i)) {
T |= st[i];
}
}
ll sum = (1ll << (n - 1 - __builtin_popcountll (T)));
if (cnt & 1)   sum *= -1ll; //容斥系数
return sum;
}

int main () {
memset (h, -1, sizeof h);
cin >> n;
for (int i = 1; i < n; i++) {
int a, b;
cin >> a >> b;
}
cin >> m;
dfs (1, -1);

for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
st[i] = d[a] ^ d[b]; //经典的树上异或性质:x到y的路径上的边的状压数值
}
ll ans = 0;
//0的状态是全集
for (ll i = 0; i < (1ll << m); i++)    ans += count (i);
cout << ans << endl;
}
``````
————————

### AtCoder Beginner Contest 152

https://atcoder.jp/contests/abc152
F我看了半天，编码方式那里还算是感觉比较玄乎，这题确实妙。

### D – Handstand 2

``````#include <bits/stdc++.h>
#define ll long long

using namespace std;
ll n, sum, a[10][10];
ll pw[] = {1, 10, 100, 1000, 10000, 100000, 1000000};

int main () {
cin >> n;
for (int i = 1; i <= n; i++)    a[i / pw[(int)to_string (i).size () - 1]][i % 10] ++;
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
sum += a[i][j] * a[j][i];
}
}
cout << sum;
}

//只存首尾
``````

### E – Flatten

``````#include <bits/stdc++.h>
#define ll long long

using namespace std;
typedef pair<int, int> pii;
const int N = 1e4 + 5, mod = 1e9 + 7, M = 1e6 + 5;// M = 78499 + 5; //1e6以内素数的个数
int n, a[N], cnt[M];
ll sum;

ll qmi(ll a, ll k, ll p){
ll res = 1;
while(k){
if(k & 1)
res = (ll)res * a % p;
a = (ll)a * a % p;
k >>= 1;
}
return res;
}

int main () {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
// cout << a[i] << ":\n";
int t = a[i];
for (int j = 2; j * j <= t; j++) {
if (t % j == 0) {
int tt = 0;
while (t % j == 0)    t /= j, tt++;
cnt[j] = max (tt, cnt[j]);
}
}
if (t > 1)   cnt[t] = max (cnt[t], 1);
}

ll mul = 1;
for (int i = 1; i < M; i++) {
while (cnt[i]--)    (mul *= i) %= mod;
}
for (int i = 1; i <= n; i++)    (sum += mul % mod * qmi (a[i], mod - 2, mod)) %= mod;
cout << sum;
}

//d/ai求和
//对ai进行素因数分解
``````

### F – Tree and Constraints

https://www.luogu.com.cn/blog/subtlemaple/solution-at-abc152-f

``````#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 55;
int h[N], e[N*2], ne[N*2], idx;
ll n, m, d[N], st[N]; //di为限制条件, st[i]当前边状态

void add (int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void dfs (int u, int fa) {
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (j == fa)    continue;
d[j] = d[u] | (1ll << (j - 1)); //根节点到 x 经过的边的状压数值
dfs (j, u);
}
}

ll count (ll S) { //f(S) = 2^{n-1-|S|}
ll cnt = __builtin_popcountll (S), T = 0; //T为并集
for (int i = 0; i < m; i++) {
if (S & (1ll << i)) {
T |= st[i];
}
}
ll sum = (1ll << (n - 1 - __builtin_popcountll (T)));
if (cnt & 1)   sum *= -1ll; //容斥系数
return sum;
}

int main () {
memset (h, -1, sizeof h);
cin >> n;
for (int i = 1; i < n; i++) {
int a, b;
cin >> a >> b;
}
cin >> m;
dfs (1, -1);

for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
st[i] = d[a] ^ d[b]; //经典的树上异或性质:x到y的路径上的边的状压数值
}
ll ans = 0;
//0的状态是全集
for (ll i = 0; i < (1ll << m); i++)    ans += count (i);
cout << ans << endl;
}
``````