zoukankan      html  css  js  c++  java
  • 2017 CCPC秦皇岛 G题 Numbers

    DreamGrid has a nonnegative integer . He would like to divide  into nonnegative integers  and minimizes their bitwise or (i.e.  and  should be as small as possible).

    Input

    There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case:

    The first line contains two integers  and  ().

    It is guaranteed that the sum of the length of  does not exceed .

    <h4< dd="">Output

    For each test case, output an integer denoting the minimum value of their bitwise or.

    <h4< dd="">Sample Input

    5
    3 1
    3 2
    3 3
    10000 5
    1244 10

    <h4< dd="">Sample Output

    3
    3
    1
    2000
    125
    题解:题意很简单,就是让你把n分成m份,然后让你求这m份按位或的最小值;(注意数据范围,大数模板考虑下Orz)
    考虑一个k满足m*2^k <= n < m*2^(k+1)如果使得结果最小,则对于分开后,每个数的最高位(二进制)位置越小,找到一个k后,我们让这m个数字第k位都为一。
    然后剩下n-m*2^k(相当于新的n),递归求解即可;
    参考代码:
      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 // base and base_digits must be consistent
      4 constexpr int base = 1000000000;
      5 constexpr int base_digits = 9;
      6 struct bigint
      7 {
      8     vector<int> z;
      9     int sign;
     10     bigint() : sign(1) {}
     11     bigint(long long v)
     12     {
     13         *this = v;
     14     }
     15     bigint& operator=(long long v)
     16     {
     17         sign = v < 0 ? -1 : 1;
     18         v *= sign;
     19         z.clear();
     20         for(; v > 0; v = v / base) z.push_back((int)(v % base));
     21         return *this;
     22     }
     23 
     24     bigint(const string& s)
     25     {
     26         read(s);
     27     }
     28 
     29     bigint& operator+=(const bigint& other)
     30     {
     31         if (sign == other.sign)
     32         {
     33             for (int i = 0, carry = 0; i < other.z.size() || carry; ++i)
     34             {
     35                 if(i == z.size()) z.push_back(0);
     36                 z[i] += carry + (i < other.z.size() ? other.z[i] : 0);
     37                 carry = z[i] >= base;
     38                 if(carry) z[i] -= base;
     39             }
     40         }
     41         else if (other != 0 /* prevent infinite loop */)
     42         {
     43             *this -= -other;
     44         }
     45         return *this;
     46     }
     47 
     48     friend bigint operator+(bigint a, const bigint& b)
     49     {
     50         return a += b;
     51     }
     52 
     53     bigint& operator-=(const bigint& other)
     54     {
     55         if (sign == other.sign)
     56         {
     57             if (sign == 1 && *this >= other || sign == -1 && *this <= other)
     58             {
     59                 for (int i = 0, carry = 0; i < other.z.size() || carry; ++i)
     60                 {
     61                     z[i] -= carry + (i < other.z.size() ? other.z[i] : 0);
     62                     carry = z[i] < 0;
     63                     if(carry) z[i] += base;
     64                 }
     65                 trim();
     66             }
     67             else
     68             {
     69                 *this = other - *this;
     70                 this->sign = -this->sign;
     71             }
     72         }
     73         else *this += -other;
     74         return *this;
     75     }
     76 
     77     friend bigint operator - (bigint a, const bigint& b)
     78     {
     79         return a -= b;
     80     }
     81 
     82     bigint& operator*=(int v)
     83     {
     84         if(v < 0) sign = -sign, v = -v;
     85         for(int i = 0, carry = 0; i < z.size() || carry; ++i)
     86         {
     87             if(i == z.size()) z.push_back(0);
     88             long long cur = (long long)z[i] * v + carry;
     89             carry = (int)(cur / base);
     90             z[i] = (int)(cur % base);
     91         }
     92         trim();
     93         return *this;
     94     }
     95 
     96     bigint operator*(int v) const
     97     {
     98         return bigint(*this) *= v;
     99     }
    100 
    101     friend pair<bigint, bigint> divmod(const bigint& a1, const bigint& b1)
    102     {
    103         int norm = base / (b1.z.back() + 1);
    104         bigint a = a1.abs() * norm;
    105         bigint b = b1.abs() * norm;
    106         bigint q, r;
    107         q.z.resize(a.z.size());
    108 
    109         for (int i = (int)a.z.size() - 1; i >= 0; i--)
    110         {
    111             r *= base;
    112             r += a.z[i];
    113             int s1 = b.z.size() < r.z.size() ? r.z[b.z.size()] : 0;
    114             int s2 = b.z.size() - 1 < r.z.size() ? r.z[b.z.size() - 1] : 0;
    115             int d = (int)(((long long)s1 * base + s2) / b.z.back());
    116             r -= b * d;
    117             while(r < 0) r += b, --d;
    118             q.z[i] = d;
    119         }
    120 
    121         q.sign = a1.sign * b1.sign;
    122         r.sign = a1.sign;
    123         q.trim();
    124         r.trim();
    125         return {q, r / norm};
    126     }
    127 
    128     friend bigint sqrt(const bigint& a1)
    129     {
    130         bigint a = a1;
    131         while(a.z.empty() || a.z.size() % 2 == 1) a.z.push_back(0);
    132 
    133         int n = a.z.size();
    134         int firstDigit = (int)::sqrt((double)a.z[n - 1] * base + a.z[n - 2]);
    135         int norm = base / (firstDigit + 1);
    136         a *= norm;
    137         a *= norm;
    138         while(a.z.empty() || a.z.size() % 2 == 1) a.z.push_back(0);
    139 
    140         bigint r = (long long)a.z[n - 1] * base + a.z[n - 2];
    141         firstDigit = (int)::sqrt((double)a.z[n - 1] * base + a.z[n - 2]);
    142         int q = firstDigit;
    143         bigint res;
    144         for (int j = n / 2 - 1; j >= 0; j--)
    145         {
    146             for(;; --q)
    147             {
    148                 bigint r1 = (r - (res * 2 * base + q) * q) * base * base + (j > 0 ? (long long)a.z[2 * j - 1] * base + a.z[2 * j - 2] : 0);
    149                 if(r1 >= 0)
    150                 {
    151                     r = r1;
    152                     break;
    153                 }
    154             }
    155             res *= base;
    156             res += q;
    157             if(j > 0)
    158             {
    159                 int d1 = res.z.size() + 2 < r.z.size() ? r.z[res.z.size() + 2] : 0;
    160                 int d2 = res.z.size() + 1 < r.z.size() ? r.z[res.z.size() + 1] : 0;
    161                 int d3 = res.z.size() < r.z.size() ? r.z[res.z.size()] : 0;
    162                 q = (int)(((long long)d1 * base * base + (long long)d2 * base + d3) / (firstDigit * 2));
    163             }
    164         }
    165 
    166         res.trim();
    167         return res / norm;
    168     }
    169 
    170     bigint operator/(const bigint& v) const
    171     {
    172         return divmod(*this, v).first;
    173     }
    174 
    175     bigint operator%(const bigint& v) const
    176     {
    177         return divmod(*this, v).second;
    178     }
    179 
    180     bigint& operator/=(int v)
    181     {
    182         if(v < 0) sign = -sign, v = -v;
    183         for (int i = (int)z.size() - 1, rem = 0; i >= 0; --i)
    184         {
    185             long long cur = z[i] + rem * (long long)base;
    186             z[i] = (int)(cur / v);
    187             rem = (int)(cur % v);
    188         }
    189         trim();
    190         return *this;
    191     }
    192 
    193     bigint operator/(int v) const
    194     {
    195         return bigint(*this) /= v;
    196     }
    197 
    198     int operator%(int v) const
    199     {
    200         if(v < 0) v = -v;
    201         int m = 0;
    202         for(int i = (int)z.size() - 1; i >= 0; --i) m = (int)((z[i] + m * (long long)base) % v);
    203         return m * sign;
    204     }
    205 
    206     bigint& operator*=(const bigint& v)
    207     {
    208         *this = *this * v;
    209         return *this;
    210     }
    211 
    212     bigint& operator/=(const bigint& v)
    213     {
    214         *this = *this / v;
    215         return *this;
    216     }
    217 
    218     bool operator<(const bigint& v) const
    219     {
    220         if(sign != v.sign) return sign < v.sign;
    221         if(z.size() != v.z.size()) return z.size() * sign < v.z.size() * v.sign;
    222         for(int i = (int)z.size() - 1; i >= 0; i--)
    223             if(z[i] != v.z[i])  return z[i] * sign < v.z[i] * sign;
    224         return false;
    225     }
    226 
    227     bool operator>(const bigint& v) const
    228     {
    229         return v < *this;
    230     }
    231     bool operator<=(const bigint& v) const
    232     {
    233         return !(v < *this);
    234     }
    235     bool operator>=(const bigint& v) const
    236     {
    237         return !(*this < v);
    238     }
    239     bool operator==(const bigint& v) const
    240     {
    241         return !(*this < v) && !(v < *this);
    242     }
    243     bool operator!=(const bigint& v) const
    244     {
    245         return *this < v || v < *this;
    246     }
    247 
    248     void trim()
    249     {
    250         while(!z.empty() && z.back() == 0) z.pop_back();
    251         if(z.empty()) sign = 1;
    252     }
    253 
    254     bool isZero() const
    255     {
    256         return z.empty();
    257     }
    258 
    259     friend bigint operator-(bigint v)
    260     {
    261         if(!v.z.empty()) v.sign = -v.sign;
    262         return v;
    263     }
    264 
    265     bigint abs() const
    266     {
    267         return sign == 1 ? *this : -*this;
    268     }
    269 
    270     long long longValue() const
    271     {
    272         long long res = 0;
    273         for(int i = (int)z.size() - 1; i >= 0; i--) res = res * base + z[i];
    274         return res * sign;
    275     }
    276 
    277     friend bigint gcd(const bigint& a, const bigint& b)
    278     {
    279         return b.isZero() ? a : gcd(b, a % b);
    280     }
    281 
    282     friend bigint lcm(const bigint& a, const bigint& b)
    283     {
    284         return a / gcd(a, b) * b;
    285     }
    286 
    287     void read(const string& s)
    288     {
    289         sign = 1;
    290         z.clear();
    291         int pos = 0;
    292         while(pos < s.size() && (s[pos] == '-' || s[pos] == '+'))
    293         {
    294             if(s[pos] == '-') sign = -sign;
    295             ++pos;
    296         }
    297         for(int i = (int)s.size() - 1; i >= pos; i -= base_digits)
    298         {
    299             int x = 0;
    300             for(int j = max(pos, i - base_digits + 1); j <= i; j++) x = x * 10 + s[j] - '0';
    301             z.push_back(x);
    302         }
    303         trim();
    304     }
    305 
    306     friend istream& operator>>(istream& stream, bigint& v)
    307     {
    308         string s;
    309         stream >> s;
    310         v.read(s);
    311         return stream;
    312     }
    313 
    314     friend ostream& operator<<(ostream& stream, const bigint& v)
    315     {
    316         if(v.sign == -1) stream << '-';
    317         stream << (v.z.empty() ? 0 : v.z.back());
    318         for(int i = (int)v.z.size() - 2; i >= 0; --i)
    319             stream << setw(base_digits) << setfill('0') << v.z[i];
    320         return stream;
    321     }
    322 
    323     static vector<int> convert_base(const vector<int>& a, int old_digits, int new_digits)
    324     {
    325         vector<long long> p(max(old_digits, new_digits) + 1);
    326         p[0] = 1;
    327         for(int i = 1; i < p.size(); i++) p[i] = p[i - 1] * 10;
    328         vector<int> res;
    329         long long cur = 0;
    330         int cur_digits = 0;
    331         for(int v : a)
    332         {
    333             cur += v * p[cur_digits];
    334             cur_digits += old_digits;
    335             while (cur_digits >= new_digits)
    336             {
    337                 res.push_back(int(cur % p[new_digits]));
    338                 cur /= p[new_digits];
    339                 cur_digits -= new_digits;
    340             }
    341         }
    342         res.push_back((int)cur);
    343         while(!res.empty() && res.back() == 0)
    344             res.pop_back();
    345         return res;
    346     }
    347 
    348     typedef vector<long long> vll;
    349     static vll karatsubaMultiply(const vll& a, const vll& b)
    350     {
    351         int n = a.size();
    352         vll res(n + n);
    353         if(n <= 32)
    354         {
    355             for (int i = 0; i < n; i++)
    356                 for (int j = 0; j < n; j++)
    357                     res[i + j] += a[i] * b[j];
    358             return res;
    359         }
    360 
    361         int k = n >> 1;
    362         vll a1(a.begin(), a.begin() + k);
    363         vll a2(a.begin() + k, a.end());
    364         vll b1(b.begin(), b.begin() + k);
    365         vll b2(b.begin() + k, b.end());
    366         vll a1b1 = karatsubaMultiply(a1, b1);
    367         vll a2b2 = karatsubaMultiply(a2, b2);
    368         for(int i = 0; i < k; i++) a2[i] += a1[i];
    369         for(int i = 0; i < k; i++) b2[i] += b1[i];
    370 
    371         vll r = karatsubaMultiply(a2, b2);
    372         for(int i = 0; i < a1b1.size(); i++) r[i] -= a1b1[i];
    373         for(int i = 0; i < a2b2.size(); i++) r[i] -= a2b2[i];
    374         for(int i = 0; i < r.size(); i++) res[i + k] += r[i];
    375         for(int i = 0; i < a1b1.size(); i++) res[i] += a1b1[i];
    376         for(int i = 0; i < a2b2.size(); i++) res[i + n] += a2b2[i];
    377         return res;
    378     }
    379 
    380     bigint operator*(const bigint& v) const
    381     {
    382         vector<int> a6 = convert_base(this->z, base_digits, 6);
    383         vector<int> b6 = convert_base(v.z, base_digits, 6);
    384         vll a(a6.begin(), a6.end());
    385         vll b(b6.begin(), b6.end());
    386         while(a.size() < b.size()) a.push_back(0);
    387         while(b.size() < a.size()) b.push_back(0);
    388         while(a.size() & (a.size() - 1)) a.push_back(0), b.push_back(0);
    389         vll c = karatsubaMultiply(a, b);
    390         bigint res;
    391         res.sign = sign * v.sign;
    392         for (int i = 0, carry = 0; i < c.size(); i++)
    393         {
    394             long long cur = c[i] + carry;
    395             res.z.push_back((int)(cur % 1000000));
    396             carry = (int)(cur / 1000000);
    397         }
    398         res.z = convert_base(res.z, 6, base_digits);
    399         res.trim();
    400         return res;
    401     }
    402 };
    403 /***********************************************
    404      上面为大数模板 核心代码
    405 ************************************************/
    406 int main()
    407 {
    408     ios::sync_with_stdio(0);
    409     cin.tie(0);
    410     bigint n, m;
    411     int T;
    412     cin >> T;
    413     while(T--)
    414     {
    415         cin >> n >> m;
    416         bigint ans = 0;
    417         bigint now = 1;
    418         while(now<= n)
    419         {
    420             now = now * 2;
    421         }
    422         while(n != 0)
    423         {
    424             while(now != 1 && now * m > n)
    425             {
    426                 now = now / 2;
    427             }
    428             if((now * 2 - 1) * m < n)
    429                 now = now * 2;
    430             bigint num = n / now;
    431             if(num > m)
    432                 num = m;
    433             n = n - num * now;
    434             ans = ans + now;
    435         }
    436         cout << ans << endl;
    437     }
    438     return 0;
    439 } 
    440   
    View Code
  • 相关阅读:
    javascript学习笔记(一):基础、输出、注释、引用、变量、数据类型
    black-hole《XSS的原理分析与解剖》阅读笔记
    《xss跨站脚本剖析与防御》实验笔记
    XSS和CSRF的区别
    前端常用插件、工具类库汇总(下)
    前端常用插件、工具类库汇总(上)
    前端特效【第03期】|果汁混合效果-上
    玩转 React 【第03期】:邂逅 React 组件
    前端修炼の道 | 如何成为一名合格前端开发工程师?
    前端特效【第02期】|多功能提交按钮
  • 原文地址:https://www.cnblogs.com/csushl/p/9787729.html
Copyright © 2011-2022 走看看