zoukankan      html  css  js  c++  java
  • 【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.
  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/myx12345/p/6060588.html
Copyright © 2011-2022 走看看