A. marshland

考试时想到了网络流,然而不会建图,就死了。

正解是最大费用可行流。

比较容易想到的是将每个点拆为两个点,

s连没有危险值的入点,

没有危险值的入点连有危险值的入点,入点出点之间限流有费用,

出点再连没有危险值的出点,这些出点连向t。

不断跑spfa,通过有流量的边,记录下前趋。

将前趋的边的流量改变,EK算法。

 

 

 

B. party

因为只有单向边,达成尽快到齐的条件是,终点为c个点的lca。

m的范围比较小,于是可以用bitset维护。

比较容易想到了在倍增求lca的同时维护bitset,取并集。

然而空间刚好卡到600多MB,时间也死了。

树链剖分。

空间返回到O(n*m)级别,比倍增少一个log。

问题转化为每个人从自己所有集合中选择相同数量的最多元素,要求互不相同。

网络流+二分可行。

源点向每个人建流量为mid的边,每个人向它包含元素建流量为1的边,每个元素向汇点建流量为1的边。

左部点流满就表示可行。

如果将每个人拆为若干个点,问题其实是求二分图完美匹配。

于是想到霍尔定理(???):

一个二分图 G 存在完美匹配, 当且仅当 X 中的任意 k 个点都至少与 Y 中的 k 个点邻接.

二分答案,枚举$2^{c*mid}$显然是可行的,然而复杂度真的死了。

考虑不同的左部点只有c个,枚举$2^c$,

1表示考虑这个人。

将答案与 所有考虑的人的bitset并集中1的个数除以考虑的人数 取min。

总复杂度为$O(\frac{qlog^2nm}{32})$。

考虑到没有修改操作,直接维护每个点到重链顶的bitset,可以将复杂度降低一个$logn$。

推荐$unsigned long long$手写$bitset$,

主要是可以将$O(n)$的$count$函数通过预处理变成$O(\frac{n}{32})$,

或者继续循环展开将所有操作改为$O(1)$。

 1 struct bitset{
 2     #define lowbit(x) (x&-x)
 3     unsigned long long bit[16];
 4     inline void reset(){
 5         bit[0]=0;
 6         bit[1]=0;
 7         bit[2]=0;
 8         bit[3]=0;
 9         bit[4]=0;
10         bit[5]=0;
11         bit[6]=0;
12         bit[7]=0;
13         bit[8]=0;
14         bit[9]=0;
15         bit[10]=0;
16         bit[11]=0;
17         bit[12]=0;
18         bit[13]=0;
19         bit[14]=0;
20         bit[15]=0;
21     }
22     inline friend void operator |=(bitset &a,const bitset &b){
23         a.bit[0]|=b.bit[0];
24         a.bit[1]|=b.bit[1];
25         a.bit[2]|=b.bit[2];
26         a.bit[3]|=b.bit[3];
27         a.bit[4]|=b.bit[4];
28         a.bit[5]|=b.bit[5];
29         a.bit[6]|=b.bit[6];
30         a.bit[7]|=b.bit[7];
31         a.bit[8]|=b.bit[8];
32         a.bit[9]|=b.bit[9];
33         a.bit[10]|=b.bit[10];
34         a.bit[11]|=b.bit[11];
35         a.bit[12]|=b.bit[12];
36         a.bit[13]|=b.bit[13];
37         a.bit[14]|=b.bit[14];
38         a.bit[15]|=b.bit[15];
39     }
40     inline friend bitset operator |(const bitset &a,const bitset &b){
41         bitset ans;
42         ans.bit[0]=a.bit[0]|b.bit[0];
43         ans.bit[1]=a.bit[1]|b.bit[1];
44         ans.bit[2]=a.bit[2]|b.bit[2];
45         ans.bit[3]=a.bit[3]|b.bit[3];
46         ans.bit[4]=a.bit[4]|b.bit[4];
47         ans.bit[5]=a.bit[5]|b.bit[5];
48         ans.bit[6]=a.bit[6]|b.bit[6];
49         ans.bit[7]=a.bit[7]|b.bit[7];
50         ans.bit[8]=a.bit[8]|b.bit[8];
51         ans.bit[9]=a.bit[9]|b.bit[9];
52         ans.bit[10]=a.bit[10]|b.bit[10];
53         ans.bit[11]=a.bit[11]|b.bit[11];
54         ans.bit[12]=a.bit[12]|b.bit[12];
55         ans.bit[13]=a.bit[13]|b.bit[13];
56         ans.bit[14]=a.bit[14]|b.bit[14];
57         ans.bit[15]=a.bit[15]|b.bit[15];
58         return ans;
59     }
60     inline void set(const int x){
61         bit[x>>6]|=(unsigned long long)1<<(x&63);
62     }
63     inline int count(){
64         register int cnt=0;
65         cnt+=ct[bit[0]&65535]+ct[(bit[0]>>16)&65535]+ct[(bit[0]>>32)&65535]+ct[(bit[0]>>48)&65535];
66         cnt+=ct[bit[1]&65535]+ct[(bit[1]>>16)&65535]+ct[(bit[1]>>32)&65535]+ct[(bit[1]>>48)&65535];
67         cnt+=ct[bit[2]&65535]+ct[(bit[2]>>16)&65535]+ct[(bit[2]>>32)&65535]+ct[(bit[2]>>48)&65535];
68         cnt+=ct[bit[3]&65535]+ct[(bit[3]>>16)&65535]+ct[(bit[3]>>32)&65535]+ct[(bit[3]>>48)&65535];
69         cnt+=ct[bit[4]&65535]+ct[(bit[4]>>16)&65535]+ct[(bit[4]>>32)&65535]+ct[(bit[4]>>48)&65535];
70         cnt+=ct[bit[5]&65535]+ct[(bit[5]>>16)&65535]+ct[(bit[5]>>32)&65535]+ct[(bit[5]>>48)&65535];
71         cnt+=ct[bit[6]&65535]+ct[(bit[6]>>16)&65535]+ct[(bit[6]>>32)&65535]+ct[(bit[6]>>48)&65535];
72         cnt+=ct[bit[7]&65535]+ct[(bit[7]>>16)&65535]+ct[(bit[7]>>32)&65535]+ct[(bit[7]>>48)&65535];
73         cnt+=ct[bit[8]&65535]+ct[(bit[8]>>16)&65535]+ct[(bit[8]>>32)&65535]+ct[(bit[8]>>48)&65535];
74         cnt+=ct[bit[9]&65535]+ct[(bit[9]>>16)&65535]+ct[(bit[9]>>32)&65535]+ct[(bit[9]>>48)&65535];
75         cnt+=ct[bit[10]&65535]+ct[(bit[10]>>16)&65535]+ct[(bit[10]>>32)&65535]+ct[(bit[10]>>48)&65535];
76         cnt+=ct[bit[11]&65535]+ct[(bit[11]>>16)&65535]+ct[(bit[11]>>32)&65535]+ct[(bit[11]>>48)&65535];
77         cnt+=ct[bit[12]&65535]+ct[(bit[12]>>16)&65535]+ct[(bit[12]>>32)&65535]+ct[(bit[12]>>48)&65535];
78         cnt+=ct[bit[13]&65535]+ct[(bit[13]>>16)&65535]+ct[(bit[13]>>32)&65535]+ct[(bit[13]>>48)&65535];
79         cnt+=ct[bit[14]&65535]+ct[(bit[14]>>16)&65535]+ct[(bit[14]>>32)&65535]+ct[(bit[14]>>48)&65535];
80         cnt+=ct[bit[15]&65535]+ct[(bit[15]>>16)&65535]+ct[(bit[15]>>32)&65535]+ct[(bit[15]>>48)&65535];
81         return cnt;
82     }
83 };
View Code

 

 

 

C. platform

后缀数组。

然而完全忘记了怎么打。

没改到,鸽了。