zoukankan      html  css  js  c++  java
  • Gym

    Decoding of Varints

    Statements

    Varint is a type used to serializing integers using one or more bytes. The key idea is to have smaller values being encoded with a smaller number of bytes.

    First, we would like to encode some unsigned integer x. Consider its binary representation x = a0a1a2... ak - 1, where ai-th stands for the i-th significant bit, i.e. x = a0·20 + a1·21 + ... + ak - 1·2k - 1, while k - 1 stands for the index of the most significant bit set to 1 or k = 1 if x = 0.

    To encode x we will use bytes b0, b1, ..., bm - 1. That means one byte for integers from 0 to 127, two bytes for integers from 128 to 214 - 1 = 16383 and so on, up to ten bytes for 264 - 1. For bytes b0, b1, ..., bm - 2 the most significant bit is set to 1, while for byte bm - 1 it is set to 0. Then, for each i from 0 to k - 1, i mod 7 bit of byte is set to ai. Thus,

    x = (b0 - 128)·20 + (b1 - 128)·27 + (b2 - 128)·214 + ... + (bm - 2 - 128)·27·(m - 2) + bm - 1·27·(m - 1)

    In the formula above we subtract 128 from b0, b1, ..., bm - 2 because their most significant bit was set to 1.

    For example, integer 7 will be represented as a single byte b0 = 7, while integer 260 is represented as two bytes b0 = 132 and b1 = 2.

    To represent signed integers we introduce ZigZag encoding. As we want integers of small magnitude to have short representation we map signed integers to unsigned integers as follows. Integer 0 is mapped to 0,  - 1 to 1, 1 to 2,  - 2 to 3, 2 to 4,  - 3 to 5, 3 to 6 and so on, hence the name of the encoding. Formally, if x ≥ 0, it is mapped to 2x, while if x < 0, it is mapped to  - 2x - 1.

    For example, integer 75 is mapped to 150 and is encoded as b0 = 150, b1 = 1, while  - 75 will be mapped to 149 and will be encoded as b0 = 149, b1 = 1. In this problem we only consider such encoding for integers from  - 263 to 263 - 1 inclusive.

    You are given a sequence of bytes that corresponds to a sequence of signed integers encoded as varints. Your goal is to decode and print the original sequence.

    Input

    The first line of the input contains one integer n (1 ≤ n ≤ 10 000) — the length of the encoded sequence. The next line contains n integers from 0 to 255. You may assume that the input is correct, i.e. there exists a sequence of integers from  - 263 to 263 - 1 that is encoded as a sequence of bytes given in the input.

    Output

    Print the decoded sequence of integers.

    Example
    Input
    5
    0 194 31 195 31
    Output
    0
    2017
    -2018



    首先需要用unsigned long long,除2前值为long long的两倍。
    再一个就是先除2再加1,避免先加后值越界。


    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ll;
    const int MAX = 10005;
    
    ll mi[65];
    ll a[MAX];
    
    void init(){
        mi[0]=1;
        for(ll i=1;i<=63;i++){
            mi[i]=mi[i-1]*2;
        }
    }
    int main(void)
    {
        int t,i,j;
        ll n,x;
        init();
        scanf("%I64u",&n);
        for(i=1;i<=n;i++){
            scanf("%I64u",&a[i]);
        }
        ll ans=0;int l=0;
        for(i=1;i<=n;i++){
            if(a[i]<128){
                ans+=a[i]*mi[l*7];
                if(ans&1) printf("-%I64u
    ",ans/2+1);
                else printf("%I64u
    ",ans/2);
    
                ans=0;l=0;
                continue;
            }
            ans+=(a[i]-128)*mi[l*7];
            l++;
        }
        return 0;
    }
  • 相关阅读:
    云服务器迁移的那些事之一
    《编译原理》(第二版)第一章的学习笔记(一)
    vs 实用扩展
    SQL多的是,你不知道的事
    Entity Framework 批量插入 提速
    oracle 回收已删除的表
    发现一个奇怪的问题!
    看到易办网的希望...
    asp.net不认为数据库字段的空值为null
    什么是伪url?
  • 原文地址:https://www.cnblogs.com/yzm10/p/9716057.html
Copyright © 2011-2022 走看看