• 19-10-26-Night-D


    压表的技巧。

    ZJ一下:

    T1,考试不会哈夫曼树只压到$1MB$最后截掉了一部分。

    T2,直接暴力丢上去。$Theta(N+sqrt{N}log N)$

    T3,现场码出左右旋然后就不会了$QAQ$

    TJ一下:

    T1

    先讲讲考试打的是什么表。

    首先码了一个$Dijkstra$,然后它跑的还挺快,$3s$可以直接打出全部的答案。(比跑不出来的暴力好不少……)

    于是把表打出来,因为我考虑到16进制的数可能短于10进制。于是使用了$0x$。

    发现……$3MB$。

    我……然后顺手打了一下10进制。……$2MB$(数值足够小的时候前导会大量冗余)

    那么又看了一眼最大值,48……进一步压表,每一个数就可以用1个字。

    最后$1MB$

    后记:

    ——极限压表。

    先摆上压之前的,长这个样:

    记0:

    为了方便压表,将原序列转化成前缀和形式。

    从48种字符处理成11种,

    便于下面的压表。

    记1:

    使用相等字符压表。压缩效果并不好……实测无效=.=

    效果:

    不使用前缀和优化:

    ××我要前缀和有何用

    下面有用(滑稽

    附:前缀和后相等的串长会全部减一,于是就会导致连续相等字符数减少于是前缀和压缩效果会变差

    记2:

    处理成前缀和后,可以将两个字符暴力压成一个……

    $11$进制,两位是$121$,一个$char$是$127$,挺好。

    但是问题在于在$mathsf{ASCII}$表码上找不到一段长度$geq 121$的有效字符?

    下面是打出来的表码

    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  0
    49  1
    50  2
    51  3
    52  4
    53  5
    54  6
    55  7
    56  8
    57  9
    58  :
    59  ;
    60  <
    61  =
    62  >
    63  ?
    64  @
    65  A
    66  B
    67  C
    68  D
    69  E
    70  F
    71  G
    72  H
    73  I
    74  J
    75  K
    76  L
    77  M
    78  N
    79  O
    80  P
    81  Q
    82  R
    83  S
    84  T
    85  U
    86  V
    87  W
    88  X
    89  Y
    90  Z
    91  [
    92  
    93  ]
    94  ^
    95  _
    96  `
    97  a
    98  b
    99  c
    100  d
    101  e
    102  f
    103  g
    104  h
    105  i
    106  j
    107  k
    108  l
    109  m
    110  n
    111  o
    112  p
    113  q
    114  r
    115  s
    116  t
    117  u
    118  v
    119  w
    120  x
    121  y
    122  z
    123  {
    124  |
    125  }
    126  ~
    

    是这样……

    所以实现起来可能还需要一些其他的技巧?

    理论上可以实现并压到$500KB$

    记3:

    一种专业压缩的数据结构:哈夫曼树。

    显然我去颓了一波代码。

    并且实现也像××一样。

    在前缀和后,内部的字符频数是这样的:

    G H I J K L M N O P Q
    407022 326991 169760 63867 23165 6733 1822 486 119 30 5

    那么在这棵树上是长这个样的:(这里我们用H表示0)

    编号 字母 字符频数 编码
    1 G 407022 0
    2 H 326991 11
    3 I 169760 101
    4 J 63867 1001
    5 K 23165 10001
    6 L 6733 100001
    7 M 1822 1000001
    8 N 486 10000001
    9 O 119 100000001
    10 P 30 1000000001
    11 Q 5 1000000000

    具体节点:

    编号 字符 权值 父亲 左孩子 右孩子
    1 G 407022 21 0 0
    2 H 326991 20 0 0
    3 I 169760 19 0 0
    4 J 63867 18 0 0
    5 K 23165 17 0 0
    6 L 6733 16 0 0
    7 M 1822 15 0 0
    8 N 486 14 0 0
    9 O 119 13 0 0
    10 P 30 12 0 0
    11 Q 5 12 0 0
    12 35 13 11 10
    13 154 14 12 9
    14 640 15 13 8
    15 2462 16 14 7
    16 9195 17 15 6
    17 32360 18 16 5
    18 96227 19 17 4
    19 265987 20 18 3
    20 592978 21 19 2
    21 1000000 0 1 20

    :中间节点,具体字符无影响。

    那么理论压缩后表长:$244KB$

    优秀的算法!

    依然过不了……但是可以启发思路(巨雾)

    部分内容源自ooo大神

    $$ ext{%%%ooo}$$

    建边(实际不需要建),跑$mathsf{SPFA}$,从$i$向$i-1$和$ki$跑。

    打表验证$2 leq k leq 7$即可

    用$dij$会比较卡常。

    因为这道题的特点,图比较稀疏并且有比较强的拓扑性,于是$mathsf{SPFA}$可行。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #define N 11111111
    #define re register
    
    using namespace std;
    
    typedef pair<int,int> pii;
    struct Myqueue{
    	int A[N*3],f,b;
    	void clear(){f=b=0;}
    	bool empty(){return f==b;}
    	void push(const int k){A[b++]=k;}
    	void pop(){f++;}
    	int front(){return A[f];}
    };
    Myqueue q;
    char dis[N],is_v[N];
    const char mx[]={2,3,5,7};
    void spfa(){
    	memset(dis,0x3f,sizeof dis);
    	dis[1]=0;
    	q.push(1);
    	is_v[1]=1;
    	while(!q.empty()){
    		int f=q.front();q.pop();
    		if(f-1>=0 && dis[f-1]>dis[f]+1){
    			dis[f-1]=dis[f]+1;
    			if(!is_v[f-1]){
    				q.push(f-1);
    				is_v[f-1]=1;
    			}
    		}
    		if(f!=0){
    			for(re int i=2;i<=7&&f*i<=1000000;++i){
    				if(dis[i*f]>dis[f]+i){
    					dis[i*f]=dis[f]+i;
    					if(!is_v[i*f]){
    						q.push(i*f);
    						is_v[i*f]=1;
    					}
    				}
    			}
    		}
    		is_v[f]=0;
    	}
    }
    int main(){
    	int v;
    	spfa();
    	cin>>v;
    	cout<<int(dis[v])<<endl;
    //	cout<<clock()<<endl;
    }
    

    T2

    杜教筛

    T3

    不会

  • 相关阅读:
    Java自带工具jstack故障分析的一个案例
    当spring 容器初始化完成后执行某个方法
    tomcat的maxThreads、acceptCount(最大线程数、最大排队数)
    RESTful API 设计指南
    GitHub简单使用入门
    Newton's method
    把一个文件夹下的多个excel文件合并到同一个excel的一个sheet里
    multimap的使用 in C++,同一个关键码存在多个值
    pandas把多个sheet读进一个DataFrame
    数据预处理之Minkowski距离计算
  • 原文地址:https://www.cnblogs.com/kalginamiemeng/p/Exam20191026-Night.html
Copyright © 2020-2023  润新知