2016多校T3 subset (分块,状压DP)

Posted myx12345

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016多校T3 subset (分块,状压DP)相关的知识,希望对你有一定的参考价值。

3 subset

 

 

3.1 题目  

 

一开始你有一个空集,集合可以出现重复元素,然后有个操作

 

  1. add s

 

在集合中加入数字 s。

 

  1. del s

 

在集合中删除数字 s。保证存在

 

  1. cnt s

 

查询满足 a&s = a 条件的 a 的个数

 

3.2 输入

 

第一行一个整数接下来行,每一行都是个操作中的一个

 

3.3 输出

 

对于每个 cnt 操作输出答案

 

3.4 Sample Input

 

7

 

add 11 cnt 15 add 4 add 0 cnt 6 del 4 cnt 15

 

3.5 Sample Output

 

1

 

2

 

2

 

3.6 数据

 

对于 30% 的数据满足:1 n 1000

 

对于 100% 的数据满足,1 n 200000 , 0 < s < 216

 

思路:

 

分块计算。a[pre][suf],其中 pre < 28,suf < 28,表示前面位是 pre,后面位是 suf 

子集的数字的个数。

 

那么对于每个 add  del 操作都可以最多 28 时间枚举 suf 更新数组。对于 cnt 操作,最多 28 枚举 pre,计算答案即可时间复杂度 O(n 28)

 

 1 var dp:array[0..300,0..300]of longint;
 2     s1,s2,n,i,x,j:longint;
 3     ch:string;
 4 
 5 procedure dfs1(var s1,s2:longint;k,s:longint);
 6 begin
 7  if k>7 then
 8  begin
 9   inc(dp[s1,s]);
10   exit;
11  end;
12  if s2 and (1<<k)>0 then dfs1(s1,s2,k+1,s+(1<<k))
13   else
14   begin
15    dfs1(s1,s2,k+1,s);
16    dfs1(s1,s2,k+1,s+(1<<k));
17   end;
18 end;
19 
20 procedure dfs2(var s1,s2:longint;k,s:longint);
21 begin
22  if k>7 then
23  begin
24   dec(dp[s1,s]);
25   exit;
26  end;
27  if s2 and (1<<k)>0 then dfs2(s1,s2,k+1,s+(1<<k))
28   else
29   begin
30    dfs2(s1,s2,k+1,s);
31    dfs2(s1,s2,k+1,s+(1<<k));
32   end;
33 end;
34 
35 procedure add(x:longint);
36 var i:longint;
37 begin
38  s1:=0; s2:=0;
39  for i:=15 downto 8 do
40   if x and (1<<i)>0 then s1:=s1+1<<(i-8);
41   for i:=7 downto 0 do
42    if x and (1<<i)>0 then s2:=s2+1<<i;
43  dfs1(s1,s2,0,0);
44 end;
45 
46 procedure del(x:longint);
47 var i:longint;
48 begin
49  s1:=0; s2:=0;
50  for i:=15 downto 8 do
51   if x and (1<<i)>0 then s1:=s1+1<<(i-8);
52   for i:=7 downto 0 do
53    if x and (1<<i)>0 then s2:=s2+1<<i;
54  dfs2(s1,s2,0,0);
55 end;
56 
57 function cnt(x:longint):longint;
58 var ret,i,s:longint;
59 begin
60  ret:=0;
61  s1:=0; s2:=0;
62  for i:=15 downto 8 do
63   if x and (1<<i)>0 then s1:=s1+1<<(i-8);
64  for i:=7 downto 0 do
65   if x and (1<<i)>0 then s2:=s2+1<<i;
66  s:=s1;
67  while s>0 do
68  begin
69   ret:=ret+dp[s,s2];
70   s:=s1 and (s-1);
71  end;
72  ret:=ret+dp[0,s2];
73  exit(ret);
74 end;
75 
76 begin
77  assign(input,subset.in); reset(input);
78  assign(output,subset.out); rewrite(output);
79  readln(n);
80  for i:=1 to n do
81  begin
82   readln(ch);
83   x:=0;
84   for j:=5 to length(ch) do x:=x*10+ord(ch[j])-ord(0);
85   if ch[1]=a then add(x);
86   if ch[1]=d then del(x);
87   if ch[1]=c then writeln(cnt(x));
88  end;
89  close(input);
90  close(output);
91 end.

 

以上是关于2016多校T3 subset (分块,状压DP)的主要内容,如果未能解决你的问题,请参考以下文章

2016多校T3 质数 (分块,想法题)

[NOIP2016]愤怒的小鸟 D2 T3 状压DP

HDU 6092 17多校5 Rikka with Subset(dp+思维)

11.8晚 考试总结

CF895C Square Subsets(状压dp&组合数学)

CF895C Square Subsets (组合数+状压DP+简单数论)