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),递归求解即可;
参考代码:
 #include <bits/stdc++.h>
using namespace std;
// base and base_digits must be consistent
constexpr int base = ;
constexpr int base_digits = ;
struct bigint
{
vector<int> z;
int sign;
bigint() : sign() {}
bigint(long long v)
{
*this = v;
}
bigint& operator=(long long v)
{
sign = v < ? - : ;
v *= sign;
z.clear();
for(; v > ; v = v / base) z.push_back((int)(v % base));
return *this;
} bigint(const string& s)
{
read(s);
} bigint& operator+=(const bigint& other)
{
if (sign == other.sign)
{
for (int i = , carry = ; i < other.z.size() || carry; ++i)
{
if(i == z.size()) z.push_back();
z[i] += carry + (i < other.z.size() ? other.z[i] : );
carry = z[i] >= base;
if(carry) z[i] -= base;
}
}
else if (other != /* prevent infinite loop */)
{
*this -= -other;
}
return *this;
} friend bigint operator+(bigint a, const bigint& b)
{
return a += b;
} bigint& operator-=(const bigint& other)
{
if (sign == other.sign)
{
if (sign == && *this >= other || sign == - && *this <= other)
{
for (int i = , carry = ; i < other.z.size() || carry; ++i)
{
z[i] -= carry + (i < other.z.size() ? other.z[i] : );
carry = z[i] < ;
if(carry) z[i] += base;
}
trim();
}
else
{
*this = other - *this;
this->sign = -this->sign;
}
}
else *this += -other;
return *this;
} friend bigint operator - (bigint a, const bigint& b)
{
return a -= b;
} bigint& operator*=(int v)
{
if(v < ) sign = -sign, v = -v;
for(int i = , carry = ; i < z.size() || carry; ++i)
{
if(i == z.size()) z.push_back();
long long cur = (long long)z[i] * v + carry;
carry = (int)(cur / base);
z[i] = (int)(cur % base);
}
trim();
return *this;
} bigint operator*(int v) const
{
return bigint(*this) *= v;
} friend pair<bigint, bigint> divmod(const bigint& a1, const bigint& b1)
{
int norm = base / (b1.z.back() + );
bigint a = a1.abs() * norm;
bigint b = b1.abs() * norm;
bigint q, r;
q.z.resize(a.z.size()); for (int i = (int)a.z.size() - ; i >= ; i--)
{
r *= base;
r += a.z[i];
int s1 = b.z.size() < r.z.size() ? r.z[b.z.size()] : ;
int s2 = b.z.size() - < r.z.size() ? r.z[b.z.size() - ] : ;
int d = (int)(((long long)s1 * base + s2) / b.z.back());
r -= b * d;
while(r < ) r += b, --d;
q.z[i] = d;
} q.sign = a1.sign * b1.sign;
r.sign = a1.sign;
q.trim();
r.trim();
return {q, r / norm};
} friend bigint sqrt(const bigint& a1)
{
bigint a = a1;
while(a.z.empty() || a.z.size() % == ) a.z.push_back(); int n = a.z.size();
int firstDigit = (int)::sqrt((double)a.z[n - ] * base + a.z[n - ]);
int norm = base / (firstDigit + );
a *= norm;
a *= norm;
while(a.z.empty() || a.z.size() % == ) a.z.push_back(); bigint r = (long long)a.z[n - ] * base + a.z[n - ];
firstDigit = (int)::sqrt((double)a.z[n - ] * base + a.z[n - ]);
int q = firstDigit;
bigint res;
for (int j = n / - ; j >= ; j--)
{
for(;; --q)
{
bigint r1 = (r - (res * * base + q) * q) * base * base + (j > ? (long long)a.z[ * j - ] * base + a.z[ * j - ] : );
if(r1 >= )
{
r = r1;
break;
}
}
res *= base;
res += q;
if(j > )
{
int d1 = res.z.size() + < r.z.size() ? r.z[res.z.size() + ] : ;
int d2 = res.z.size() + < r.z.size() ? r.z[res.z.size() + ] : ;
int d3 = res.z.size() < r.z.size() ? r.z[res.z.size()] : ;
q = (int)(((long long)d1 * base * base + (long long)d2 * base + d3) / (firstDigit * ));
}
} res.trim();
return res / norm;
} bigint operator/(const bigint& v) const
{
return divmod(*this, v).first;
} bigint operator%(const bigint& v) const
{
return divmod(*this, v).second;
} bigint& operator/=(int v)
{
if(v < ) sign = -sign, v = -v;
for (int i = (int)z.size() - , rem = ; i >= ; --i)
{
long long cur = z[i] + rem * (long long)base;
z[i] = (int)(cur / v);
rem = (int)(cur % v);
}
trim();
return *this;
} bigint operator/(int v) const
{
return bigint(*this) /= v;
} int operator%(int v) const
{
if(v < ) v = -v;
int m = ;
for(int i = (int)z.size() - ; i >= ; --i) m = (int)((z[i] + m * (long long)base) % v);
return m * sign;
} bigint& operator*=(const bigint& v)
{
*this = *this * v;
return *this;
} bigint& operator/=(const bigint& v)
{
*this = *this / v;
return *this;
} bool operator<(const bigint& v) const
{
if(sign != v.sign) return sign < v.sign;
if(z.size() != v.z.size()) return z.size() * sign < v.z.size() * v.sign;
for(int i = (int)z.size() - ; i >= ; i--)
if(z[i] != v.z[i]) return z[i] * sign < v.z[i] * sign;
return false;
} bool operator>(const bigint& v) const
{
return v < *this;
}
bool operator<=(const bigint& v) const
{
return !(v < *this);
}
bool operator>=(const bigint& v) const
{
return !(*this < v);
}
bool operator==(const bigint& v) const
{
return !(*this < v) && !(v < *this);
}
bool operator!=(const bigint& v) const
{
return *this < v || v < *this;
} void trim()
{
while(!z.empty() && z.back() == ) z.pop_back();
if(z.empty()) sign = ;
} bool isZero() const
{
return z.empty();
} friend bigint operator-(bigint v)
{
if(!v.z.empty()) v.sign = -v.sign;
return v;
} bigint abs() const
{
return sign == ? *this : -*this;
} long long longValue() const
{
long long res = ;
for(int i = (int)z.size() - ; i >= ; i--) res = res * base + z[i];
return res * sign;
} friend bigint gcd(const bigint& a, const bigint& b)
{
return b.isZero() ? a : gcd(b, a % b);
} friend bigint lcm(const bigint& a, const bigint& b)
{
return a / gcd(a, b) * b;
} void read(const string& s)
{
sign = ;
z.clear();
int pos = ;
while(pos < s.size() && (s[pos] == '-' || s[pos] == '+'))
{
if(s[pos] == '-') sign = -sign;
++pos;
}
for(int i = (int)s.size() - ; i >= pos; i -= base_digits)
{
int x = ;
for(int j = max(pos, i - base_digits + ); j <= i; j++) x = x * + s[j] - '';
z.push_back(x);
}
trim();
} friend istream& operator>>(istream& stream, bigint& v)
{
string s;
stream >> s;
v.read(s);
return stream;
} friend ostream& operator<<(ostream& stream, const bigint& v)
{
if(v.sign == -) stream << '-';
stream << (v.z.empty() ? : v.z.back());
for(int i = (int)v.z.size() - ; i >= ; --i)
stream << setw(base_digits) << setfill('') << v.z[i];
return stream;
} static vector<int> convert_base(const vector<int>& a, int old_digits, int new_digits)
{
vector<long long> p(max(old_digits, new_digits) + );
p[] = ;
for(int i = ; i < p.size(); i++) p[i] = p[i - ] * ;
vector<int> res;
long long cur = ;
int cur_digits = ;
for(int v : a)
{
cur += v * p[cur_digits];
cur_digits += old_digits;
while (cur_digits >= new_digits)
{
res.push_back(int(cur % p[new_digits]));
cur /= p[new_digits];
cur_digits -= new_digits;
}
}
res.push_back((int)cur);
while(!res.empty() && res.back() == )
res.pop_back();
return res;
} typedef vector<long long> vll;
static vll karatsubaMultiply(const vll& a, const vll& b)
{
int n = a.size();
vll res(n + n);
if(n <= )
{
for (int i = ; i < n; i++)
for (int j = ; j < n; j++)
res[i + j] += a[i] * b[j];
return res;
} int k = n >> ;
vll a1(a.begin(), a.begin() + k);
vll a2(a.begin() + k, a.end());
vll b1(b.begin(), b.begin() + k);
vll b2(b.begin() + k, b.end());
vll a1b1 = karatsubaMultiply(a1, b1);
vll a2b2 = karatsubaMultiply(a2, b2);
for(int i = ; i < k; i++) a2[i] += a1[i];
for(int i = ; i < k; i++) b2[i] += b1[i]; vll r = karatsubaMultiply(a2, b2);
for(int i = ; i < a1b1.size(); i++) r[i] -= a1b1[i];
for(int i = ; i < a2b2.size(); i++) r[i] -= a2b2[i];
for(int i = ; i < r.size(); i++) res[i + k] += r[i];
for(int i = ; i < a1b1.size(); i++) res[i] += a1b1[i];
for(int i = ; i < a2b2.size(); i++) res[i + n] += a2b2[i];
return res;
} bigint operator*(const bigint& v) const
{
vector<int> a6 = convert_base(this->z, base_digits, );
vector<int> b6 = convert_base(v.z, base_digits, );
vll a(a6.begin(), a6.end());
vll b(b6.begin(), b6.end());
while(a.size() < b.size()) a.push_back();
while(b.size() < a.size()) b.push_back();
while(a.size() & (a.size() - )) a.push_back(), b.push_back();
vll c = karatsubaMultiply(a, b);
bigint res;
res.sign = sign * v.sign;
for (int i = , carry = ; i < c.size(); i++)
{
long long cur = c[i] + carry;
res.z.push_back((int)(cur % ));
carry = (int)(cur / );
}
res.z = convert_base(res.z, , base_digits);
res.trim();
return res;
}
};
/***********************************************
上面为大数模板 核心代码
************************************************/
int main()
{
ios::sync_with_stdio();
cin.tie();
bigint n, m;
int T;
cin >> T;
while(T--)
{
cin >> n >> m;
bigint ans = ;
bigint now = ;
while(now<= n)
{
now = now * ;
}
while(n != )
{
while(now != && now * m > n)
{
now = now / ;
}
if((now * - ) * m < n)
now = now * ;
bigint num = n / now;
if(num > m)
num = m;
n = n - num * now;
ans = ans + now;
}
cout << ans << endl;
}
return ;
}
  

2017 CCPC秦皇岛 G题 Numbers的更多相关文章

  1. 2017 CCPC秦皇岛 A题 A Ballon Robot

    The 2017 China Collegiate Programming Contest Qinhuangdao Site is coming! There will be  teams parti ...

  2. 2017 CCPC秦皇岛 M题 Safest Buildings

    PUBG is a multiplayer online battle royale video game. In the game, up to one hundred players parach ...

  3. 2017 CCPC秦皇岛 L题 One Dimensions Dave

    BaoBao is trapped in a one-dimensional maze consisting of  grids arranged in a row! The grids are nu ...

  4. 2017 CCPC秦皇岛 E题 String of CCPC

    BaoBao has just found a string  of length  consisting of 'C' and 'P' in his pocket. As a big fan of ...

  5. 2017CCPC秦皇岛 G题Numbers&&ZOJ3987【大数】

    题意: 给出一个数n,现在要将它分为m个数,这m个数相加起来必须等于n,并且要使得这m个数的或值最小. 思路: 从二进制的角度分析,如果这m个数中有一个数某一位为1,那么最后或起来这一位肯定是为1的, ...

  6. 2017 CCPC秦皇岛 H题 Prime set

    Given an array of  integers , we say a set  is a prime set of the given array, if  and  is prime. Ba ...

  7. 2017 ccpc哈尔滨 A题 Palindrome

    2017 ccpc哈尔滨 A题 Palindrome 题意: 给一个串\(T\),计算存在多少子串S满足\(S[i]=S[2n−i]=S[2n+i−2](1≤i≤n)\) 思路: 很明显这里的回文串长 ...

  8. HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)

    题目链接  2017 CCPC Hangzhou  Problem E 题意  给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...

  9. HDU 6271 Master of Connected Component(2017 CCPC 杭州 H题,树分块 + 并查集的撤销)

    题目链接  2017 CCPC Hangzhou Problem H 思路:对树进行分块.把第一棵树分成$\sqrt{n}$块,第二棵树也分成$\sqrt{n}$块.    分块的时候满足每个块是一个 ...

随机推荐

  1. Eclipse添加自定义注释

    首先介绍几个常用的注解: @author 作者名 @date 日期 @version 版本标识 @parameter 参数及其意义 @return 返回值 @throws 异常类及抛出条件 @depr ...

  2. UML简明使用

    1.继承 空心三角+实线 2.实现接口 空心三角+虚线 3.关联 箭头+实线 4.聚合 空心菱形+实线+箭头 5.组合 实心菱形+实线+箭头 6.依赖 虚线+箭头 7.关联.聚合.组合.依赖的区别 关 ...

  3. 03-MyBatis拦截器机制

    目录 MyBatis拦截器介绍 拦截器的使用 拦截器介绍及配置 源码分析 总结 本文转载自MyBatis拦截器原理探究 MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽 ...

  4. dubbo分布式Service不可以创建Error creating bean with name 'XXXXXX'

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demoService' ...

  5. Pashmak and Parmida's problem(树状数组)

    题目链接:http://codeforces.com/contest/459/problem/D 题意: 数列A, ai表示 i-th 的值, f(i,j, x) 表示[i,j]之间x的数目, 问:当 ...

  6. python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等)

    python3 解释器默认编码为Unicode,由str类型进行表示.二进制数据使用byte类型表示. 字符串通过编码转换成字节串,字节码通过解码成为字符串. encode:str-->byte ...

  7. 【论文阅读】The Contextual Loss for Image Transformationwith Non-Aligned Data(ECCV2018 oral)

    目录: 相关链接 方法亮点 相关工作 方法细节 实验结果 总结与收获 相关链接 论文:https://arxiv.org/abs/1803.02077 代码:https://github.com/ro ...

  8. scss--函数 (Functions)--unit

    (Sass::Script::Value::String) unit($number) Returns the unit(s) associated with a number. Complex un ...

  9. 【CPLUSOJ】【动态规划】最短回文串

    题目链接 [问题描述] 如果一个字符串正过来读和倒过来读是一样的,那么这个字符串就被称作回文串.例如abcdcba,abcddbca就是回文串,而abcdabcd不是. 你要解决的问题是:对于任意一个 ...

  10. SQL SERVER中SELECT和SET赋值相同点与不同点

    SELECT和SET在SQL SERVER中都可以用来对变量进行赋值,但其用法和效果在一些细节上有些不同. 1. 在对变量赋值方面,SET是ANSI标准的赋值方式,SELECT则不是.这也是SET方式 ...