记录编号 |
249094 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[SDOI 2016] 储能表 |
最终得分 |
100 |
用户昵称 |
铁策 |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.332 s |
提交时间 |
2016-04-11 23:08:58 |
内存使用 |
2.25 MiB |
显示代码纯文本
#include <cstdio>
#include <cmath>
#define lowbit(x) (x & -x)
long long T;
long long n, m, k, p;
inline long long prod(long long x, long long y)
{
return (x % p) * (y % p) % p;
}
long long getans(long long n, long long m, long long k)
{
if (k < 0)
k = 0;
if (n == 0 || m == 0)
return 0;
if (n < m)
return getans(m, n, k);
if (lowbit(n) == n && lowbit(m) == m && n == m)
{
if (k >= n)
return 0;
long long ls = n - k - 1;
if (ls & 1)
ls = prod(ls, (n - k) / 2);
else
ls = prod(ls / 2, n - k);
ls = prod(ls, n);
return ls;
}
long long lsn = (long long)log2(n), lsm = (long long)log2(m);
if (lsn == lsm)
{
long long ls1 = getans(1LL << lsn, 1LL << lsn, k);
long long ls2 = n - (1LL << lsn);
long long ls3 = m - (1LL << lsn);
if (k >= (1LL << (lsn + 1)) - 1)
return 0;
if (k <= (1LL << lsn))
{
long long ls = (1LL << lsn) - 1;
if (ls & 1)
ls = prod(ls, (1LL << lsn) / 2);
else
ls = prod(ls / 2, 1LL << lsn);
ls = prod(ls, (ls3 % p + ls2 % p));
ls = (ls + prod(prod((1LL << lsn) - k, (ls3 % p) + (ls2 % p)), 1LL << lsn)) % p;
ls1 = (ls1 + ls) % p;
ls1 = (ls1 + getans(n & ((1LL << lsn) - 1), m & ((1LL << lsn) - 1), k)) % p;
return ls1;
}
long long lsk = k - (1LL << lsn);
long long ls = (1LL << lsn) - lsk - 1;
if (ls & 1)
ls = prod(ls, ((1LL << lsn) - lsk) / 2);
else
ls = prod(ls / 2, (1LL << lsn) - lsk);
ls = prod(ls, (ls3 % p + ls2 % p));
ls1 = (ls1 + ls) % p;
ls1 = (ls1 + getans(n & (((1LL << lsn)) - 1), m & (((1LL << lsn)) - 1), k)) % p;
return ls1;
}
else
{
long long ls = (((1LL << lsn))) - k - 1;
if (ls < 0)
ls = 0;
if (ls & 1)
ls = prod(ls, ((1LL << lsn) - k) / 2);
else
ls = prod(ls / 2, (1LL << lsn) - k);
ls = prod(ls, m);
ls = (ls + getans(n & (((1LL << lsn)) - 1), m, k - (1LL << (lsn)))) % p;
if ((1LL << lsn) - k - 1 >= 0)
ls = (ls + prod(prod((1LL << lsn) - k, m), n & ((1LL << lsn) - 1))) % p;
return ls;
}
}
int main()
{
freopen("menci_table.in", "r", stdin);
freopen("menci_table.out", "w", stdout);
scanf("%lld", &T);
for (; T > 0; T--)
{
scanf("%lld%lld%lld%lld", &n, &m, &k, &p);
printf("%lld\n", getans(n, m, k));
}
return 0;
}