• 【NOIP2016练习】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.
  • 相关阅读:
    美团这个项目是用来干啥的?
    基于C#的机器学习--面部和动态检测-图像过滤器
    基于C#的机器学习--颜色混合-自组织映射和弹性神经网络
    EF Core For Oracle11中Find FirstOrDefault等方法执行失败
    使用DataContractJsonSerializer发序列化对象时出现的异常
    数据库空值排序
    C#浅拷贝与深拷贝测试
    C#排序算法的实现---快速排序
    C#排序算法的实现---选择排序
    C#排序算法的实现---冒泡排序
  • 原文地址:https://www.cnblogs.com/myx12345/p/6060588.html
Copyright © 2020-2023  润新知