概述
为了保护ZR的版权,这里不提供题目QWQ
http://zhengruioi.com/contest/442 (你进得去吗/xyx)
A 染色
发现对于每个连通块最多剩下一棵树
答案就是
∑
边
数
−
点
数
+
1
sum 边数 - 点数 + 1
∑边数−点数+1
然后就没了
code:
#include<bits/stdc++.h>
#define N 2000005
using namespace std;
struct edge {
int v, nxt;
}e[N << 1];
int p[N], eid;
void init() {
memset(p, -1, sizeof p);
eid = 0;
}
void insert(int u, int v) {
e[eid].v = v;
e[eid].nxt = p[u];
p[u] = eid ++;
}
int n, m, vis[N], ds, bs, in[N];
void dfs(int u) {
vis[u] = 1;
bs += in[u], ds ++;
for(int i = p[u]; i + 1; i = e[i].nxt) {
int v = e[i].v;
if(!vis[v]) dfs(v);
}
}
int main() {
init();
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++) {
int u, v;
scanf("%d%d", &u, &v);
insert(u, v); in[u] ++;
insert(v, u); in[v] ++;
}
int ans = 0;
for(int i = 1; i <= n; i ++) if(!vis[i]) {
bs = 0;
ds = 0;
dfs(i);
bs /= 2;
ans += bs - ds + 1;
}
printf("%d ", ans);
return 0;
}
B 乘方
首先可以二分答案
然后考虑容斥
对于已选来的集合
(
−
1
)
k
∩
S
(
n
i
)
k
个
(-1)^k cap S(n_i) k个
(−1)k∩S(ni) k个
考虑如何计算
发现就是
S
(
l
c
m
(
n
i
)
)
S(lcm(n_i))
S(lcm(ni))
S ( x ) S(x) S(x) 可以直接用二分 + 快速幂求出来
这样只能拿部分分
发现只和
l
c
m
lcm
lcm有关
再考虑DP,
f
[
i
]
表
示
l
c
m
=
i
的
容
斥
系
数
之
和
f[i]表示lcm=i的容斥系数之和
f[i]表示lcm=i的容斥系数之和
最后答案就是
∑
f
[
i
]
S
(
i
)
sum f[i]S(i)
∑f[i]S(i)
1要特殊处理一下
然后就没了
code:
#include<bits/stdc++.h>
#define N 65
#define int long long
#define double long double
using namespace std;
int gcd(int x, int y) {
return y? gcd(y, x % y) : x;
}
int lcm(int x, int y) {
return x * y / gcd(x, y);
}
int n, m, a[N], f[N], q;
int qpow(int x, int y) {
int ret = 1;
for(; y; y >>= 1, x = x * x) if(y & 1) ret = ret * x;
return ret;
}
int find(int x, int y) {
int l = 1, r = pow(1e18, 1.0 / (double)y) + 1;
while(l + 1 < r) {
int mid = (l + r) >> 1;
if(qpow(mid, y) <= x) l = mid;
else r = mid;
}
return l;
}
int calc(int X) {
int ans = 1;
for(int i = 1; i <= 60; i ++) ans += (find(X, i) - 1) * f[i];
return ans;
}
signed main() {
scanf("%lldn", &q);
while(q --) {
memset(f, 0, sizeof f);
scanf("%lld%lld", &m, &n);
for(int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
sort(a + 1, a + 1 + n);
for(int i = 1; i <= n; i ++) {
for(int j = 60; j >= 1; j --)
if(lcm(j, a[i]) <= 60) f[lcm(j, a[i])] -= f[j];
f[a[i]] ++;
}
int l = 0, r = 1e17 + 1;
while(l + 1 < r) {
int mid = (l + r) >> 1;
if(calc(mid) >= m) r = mid;
else l = mid;
}
printf("%lldn", r);
}
return 0;
}
C 位运算
大力FWT
注意常数
最好用常数 / 2的那种写法
code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = (1 << 23) + 5;
void fwt_or(ll *a, int len, int opt){
for(int i = 1; i < len; i <<= 1)
for(int j = 0; j < len; j += i << 1)
for(register int k = j; k < j + i; k ++)
a[i + k] += (ll)opt * a[k];
}
void fwt_and(ll *a, int len, int opt){
for(int i = 1; i < len; i <<= 1)
for(int j = 0; j < len; j += i << 1)
for(register int k = j; k < j + i; k ++)
a[k] += (ll)opt * a[i + k];
}
void fwt_xor(ll *a, int len, int opt){
for(int i = 1; i < len; i <<= 1)
for(int j = 0; j < len; j += i << 1)
for(register int k = j; k < j + i; k ++){
ll X = a[k], Y = a[k + i];
a[k] = X + Y, a[k + i] = X - Y;
if(opt == -1) a[k] = (X + Y) >> 1, a[k + i] = (X - Y) >> 1;
}
}
int n, opt, cnt[N];
ll f[N], g[N];
int main(){
scanf("%d%d", &n, &opt);
int ma = 0;
for(int i = 1; i <= n; i ++) {
int x;
scanf("%d", &x);
cnt[x] ++;
f[x] ++;
ma = max(ma, x);
}
int len = (1 << 23);
// printf("%dn", len);
if(opt == 3) {
fwt_or(f, len, 1);
for(int i = 0; i < len; i ++) f[i] = f[i] * f[i];
fwt_or(f, len, -1);
for(int i = len; i >= 0; i --) if(f[i] - cnt[i] > 0) {printf("%d %lld", i, (f[i] - cnt[i]) / 2); return 0;}
}
if(opt == 1) {
fwt_and(f, len, 1);
for(int i = 0; i < len; i ++) f[i] = f[i] * f[i];
fwt_and(f, len, -1);
for(int i = len; i >= 0; i --) if(f[i] - cnt[i] > 0) {printf("%d %lld", i, (f[i] - cnt[i]) / 2); return 0;}
}
if(opt == 2) {
fwt_xor(f, len, 1);
for(int i = 0; i < len; i ++) f[i] = f[i] * f[i];
fwt_xor(f, len, -1);
for(int i = len; i >= 1; i --) if(f[i]) {printf("%d %lld", i, f[i] / 2); return 0;}
printf("0 %lld", (f[0] - n) / 2);
}
return 0;
}
总结
速度要提上去
最后
以上就是正直唇膏为你收集整理的ZR19CSP-S赛前冲刺day5A 染色B 乘方C 位运算总结的全部内容,希望文章能够帮你解决ZR19CSP-S赛前冲刺day5A 染色B 乘方C 位运算总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复