二分答案

最近失智了


更:我是zz,写出了模拟怀疑复杂度没冲

模拟:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

#include <algorithm>
#include <bitset>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <cmath>
#include <stack>
#include <set>
#include <queue>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define LL long long
#define IN freopen("in.txt", "r", stdin)
#define OUT freopen("out.txt", "w", stdout)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define sqr(x) (x) * (x)
#define pr1(x) printf("Case %d: ", x)
#define pn1(x) printf("Case %d:\n", x)
#define pr2(x) printf("Case #%d: ", x)
#define pn2(x) printf("Case #%d:\n", x)
#define lowbit(x) (x & (-x))

#define fi first
#define se second
#define sz(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;

LL tt, n, m;

int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> tt;
f(sb, 1, tt)
{
cin >> n >> m;
vector v(n, 0);
for (int i = 1, x; i <= m; ++i)
{
cin >> x;
v[x - 1] += 1;
}
sort(all(v));
multiset<int> s;
for (auto it : v)
s.insert(it);
while (*(prev(s.end())) - *s.begin() >= 3)
{
auto mi = *s.begin(), ma=*(prev(s.end()));
s.erase(s.begin());
s.erase(prev(s.end()));
ma-=1,mi+=2;
s.insert(ma);
s.insert(mi);
}
cout<<*(prev(s.end()))<<"\n";
}
return 0;
}

二分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <algorithm>
#include <bitset>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <cmath>
#include <stack>
#include <set>
#include <queue>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define LL long long
#define IN freopen("in.txt", "r", stdin)
#define OUT freopen("out.txt", "w", stdout)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define sqr(x) (x) * (x)
#define pr1(x) printf("Case %d: ", x)
#define pn1(x) printf("Case %d:\n", x)
#define pr2(x) printf("Case #%d: ", x)
#define pn2(x) printf("Case #%d:\n", x)
#define lowbit(x) (x & (-x))

#define fi first
#define se second
#define sz(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;

LL tt, n, m;

struct Node
{
int a,b;
bool operator<(const Node &bb){
return a+b*2<bb.a+bb.b*2;
}
};


int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> tt;
f(sb, 1, tt)
{
cin >> n >> m;
vector v(n, 0);
for (int i = 1, x; i <= m; ++i)
{
cin >> x;
v[x - 1] += 1;
}
LL l=1,r=m;
auto ck=[&](int x){
LL res=0;
for(auto &it:v){
if(it>x)res+=it-x;
else res-=(x-it)/2;
}
return res<=0;
};

while(l<r){
int mid=(l+r)>>1;
if(ck(mid))r=mid;
else l=mid+1;
}
cout<<r<<"\n";
}
return 0;
}

转化为最小可相交路径覆盖问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <cstdio>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;

int n, m, ans, a[21][21], mp[21][21][21][21];
char c;
bitset<404> vis;

int main()
{
scanf("%d%d", &n, &m);
vector<vector<int>> g(n * m + 1);
vector<int> f(n * m + 1, 0);

for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
scanf(" %c", &c);
ans += (c - '0');
a[i][j] = c - '0';
if(a[i][j]){
if(a[i-1][j])mp[i-1][j][i][j]=1;
if(a[i][j-1])mp[i][j-1][i][j]=1;
}
}
}

for(int kk=1;kk<=n;++kk){
for(int k=1;k<=m;++k){
for(int ii=1;ii<=n;++ii){
for(int i=1;i<=m;++i){
for(int jj=1;jj<=n;++jj){
for(int j=1;j<=m;++j){
if(ii!=jj&&i!=j){
if(mp[ii][i][kk][k]&&mp[kk][k][jj][j]){
mp[ii][i][jj][j]=1;
}
}
}
}
}
}
}
}

for(int i=1;i<=n;++i){
for(int ii=1;ii<=m;++ii){
for(int j=1;j<=n;++j){
for(int jj=1;jj<=m;++jj){
if(mp[i][ii][j][jj]){
g[(i-1)*m+ii].push_back((j-1)*m+jj);
}
}
}
}
}

function<bool(int)> ck = [&](int x) -> bool
{
for (vector<int>::iterator it = g[x].begin(); it != g[x].end(); ++it)
{
if (!vis[*it])
{
vis[*it] = 1;
if (!f[*it] || ck( f[*it]))
{
f[*it] = x;
return true;
}
}
}
return false;
};
for (int i = 1; i <= n*m; ++i)
{
vis.reset();
if (ck(i))
{
ans -= 1;
}
}

printf("%d", ans);
}

最小不相交路径覆盖问题,最小路径覆盖=原图结点数-新图匹配数

路径输出开个bitset记录每个点是否是存在后继,然后递归输出即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <cstdio>
#include <vector>
#include <bitset>
#include<iostream>
using namespace std;

int n, m,ans;
bitset<404> vis,st;


int main()
{
scanf("%d%d", &n, &m);
vector<vector<int>> g(n + 1);
vector<int> f(n + 1, 0);

for (int j = 1, x, y; j <= m; ++j)
{
scanf("%d%d", &x, &y);
g[x].push_back(y);
}
auto ck = [&](auto self, int x) -> bool
{
for (vector<int>::iterator it = g[x].begin(); it != g[x].end(); ++it)
{
if (!vis[*it])
{
vis[*it] = 1;
if (!f[*it] || self(self, f[*it]))
{
st[x]=1;
f[*it] = x;
return true;
}
}
}
return false;
};
for (int i = 1; i <= n; ++i)
{
vis.reset();
if (ck(ck, i))
{
ans += 1;
}
}

auto write=[&](int x,auto self)->void{
if(f[x]){
self(f[x],self);
printf(" %d",x);
}else printf("%d",x);
};

for(int i=1;i<=n;++i){
if(!st[i]){
write(i,write);
printf("\n");
}
}
printf("%d", n-ans);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<cstdio>
#include<bitset>
#include<vector>

using namespace std;

int k,n,m;
bitset<505> vis;

int main(){
while(~scanf("%d",&k)){
if(!k)return 0;
int ans=0;
scanf("%d%d",&n,&m);
vector<vector<int>> g(n+1);
vector<int> f(m+1);
for(int i=1,x,y;i<=k;++i)scanf("%d%d",&x,&y),g[x].push_back(y);
auto ck=[&](auto self,int x)->bool{
for(auto it:g[x]){
if(!vis[it]){
vis[it]=1;
if(!f[it]||self(self,f[it])){
f[it]=x;
return true;
}
}
}
return false;
};
for(int i=1;i<=n;++i){
vis.reset();
if(ck(ck,i))ans+=1;
}
printf("%d\n",ans);
}
}

Wordpress的编辑器对大文本的支持也太差了,,,放这备份

jls的计算几何板子

阅读全文 »
0%