QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#670698 | #7900. Gifts from Knowledge | Lynia | AC ✓ | 50ms | 50812kb | C++23 | 54.1kb | 2024-10-23 23:20:10 | 2024-10-23 23:20:10 |
Judging History
answer
///////////
// // //
// ////////////////////
// // //
//
///////////
//
//
// // // //////// /\ /////////
// // // // // // //
// //////// // // // // //
// // // // // // //
////////// //////// // // // /////////////
#pragma GCC optimize(2)
#pragma G++ optimize(2)
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <list>
#include <stack>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <random>
#include <numeric>
#include <functional>
//#include <Windows.h>
using namespace std;
#define fa(i,op,n) for (int i = op; i <= n; i++)
#define fb(j,op,n) for (int j = op; j >= n; j--)
#define pb push_back
#define HashMap unordered_map
#define HashSet unordered_set
#define var auto
#define all(i) i.begin(), i.end()
#define all1(i) i.begin() + 1,i.end()
#define endl '\n'
#define px first
#define py second
#define DEBUG(a) cout<<a<<endl
using VI = vector<int>;
using VL = vector<long long>;
using ll = long long;
using ull = unsigned long long;
using db = double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template<class T1, class T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& p) {
out << '(' << p.first << ", " << p.second << ')';
return out;
}
template<typename T>
ostream& operator<<(ostream& out, const vector<T>& ve) {
for (T i : ve)
out << i << ' ';
return out;
}
template<class T1, class T2>
ostream& operator<<(ostream& out, const map<T1, T2>& mp) {
for (auto i : mp)
out << i << '\n';
return out;
}
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int IINF = 0x7fffffff;
const int iinf = 0x80000000;
const ll LINF = 0x7FFFFFFFFFFFFFFF;
const ll linf = 0x8000000000000000;
int dx[8] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dy[8] = { 0, 0, 1, -1, 1, -1, -1, 1 };
//#include "Lynia.h"
namespace MyTools
{
template <typename T>
class Math
{
public:
static T gcd(T a, T b)
{
return b ? gcd(b, a % b) : a;
}
static T lcm(T a, T b)
{
return a / gcd(a, b) * b;
}
static T exgcd(T a, T b, T& x, T& y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
T d = exgcd(b, a % b, x, y);
T t = x;
x = y;
y = t - a / b * y;
return d;
}
static T lowbit(T k)
{
return k & (-k);
}
static T fastPow(T a, T n, T mod = 1e9 + 7)
{ // 快速幂
T ans = 1;
a %= mod;
while (n)
{
if (n & 1)
ans = (ans * a) % mod;
a = (a * a) % mod;
n >>= 1;
}
return ans;
}
static T inv(T x, T mod)
{ // 快速幂求逆
return fastPow(x, mod - 2, mod);
}
static vector<int> highPrecisionAdd(vector<int>& A, vector<int>& B)
{ // AB倒序输入
vector<int> C;
int t = 0; // 进位
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size())
t += A[i];
if (i < B.size())
t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t)
C.push_back(1);
return C; // 倒序
}
static vector<long long> factorCount(int n)
{ // 计算1-n每个数的因子个数
vector<long long> factorsCnts(n + 1);
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j += i)
factorsCnts[j]++;
return factorsCnts;
}
static set<int> factorNumbers(int n)
{ // 统计n有哪些因子
set<int> factors;
for (int i = 1; i <= n / i; i++)
{
if (n % i == 0)
{
factors.insert(i);
if (i != n / i)
factors.insert(n / i);
}
}
return factors;
}
static map<int, int> primeFactorsMAP(int n)
{ // 分解质因数
map<int, int> mp;
int m = n;
for (int i = 2; i <= n / i; i++)
{
while (m % i == 0)
{
m /= i;
mp[i]++;
}
}
if (m > 1)
mp[m]++;
return mp;
}
static set<int> primeFactorsSET(int n)
{ // 分解质因数
set<int> se;
int m = n;
for (int i = 2; i <= n / i; i++)
{
while (m % i == 0)
{
m /= i;
se.insert(i);
}
}
if (m > 1)
se.insert(m);
return se;
}
static long long C(long long a, long long b, long long mod)
{
long ans = 1;
for (long long i = 1; i <= b; i++)
{
ans = ans * (a - i + 1) % mod * fastPow(i, mod - 2, mod) % mod;
}
return ans;
}
static string decimalToBinary(int n, bool flag = 0)
{ // flag是否返回倒转 如4:100 4:001
if (n == 0)
return "0";
string binaryNumber = "";
while (n > 0)
{
binaryNumber = to_string(n % 2) + binaryNumber;
n /= 2;
}
if (!flag)
return binaryNumber;
else
{
reverse(binaryNumber.begin(), binaryNumber.end());
return binaryNumber;
}
}
};
class EulerPrime
{
public:
int cnt = 0;
vector<int> prime;
EulerPrime(int n)
{
prime.assign(n + 1, 0);
vis.assign(n + 1, 0);
init(n);
}
bool isPrime(int n)
{
if (n == 1 || n == 0)
return 0;
return !vis[n];
}
map<int, int> primeFactorsMAP(int n)
{ // 分解质因数
map<int, int> mp;
int m = n;
for (int i : prime)
{
while (m % i == 0)
{
m /= i;
mp[i]++;
}
if (isPrime(m) or m == 1) break;
}
if (m > 1)
mp[m]++;
return mp;
}
vector<int> primeFactorsVEC(int n)
{ // 欧拉筛优化分解质因数 (防多测用)
vector<int> se;
int m = n;
for (int i : prime)
{
if (m % i == 0)se.push_back(i);
while (m % i == 0)m /= i;
if (isPrime(m) or m == 1) break;
}
if (m > 1)
se.push_back(m);
return se;
}
private:
vector<bool> vis;
void init(int n) // 欧拉筛
{
for (int i = 2; i <= n; i++)
{
if (!vis[i])
prime[cnt++] = i;
for (int j = 0; j < cnt && i * prime[j] <= n; j++)
{
vis[i * prime[j]] = 1; // 用最小质因数筛去
if (i % prime[j] == 0)
break; // 不是最小质因数
}
}
}
};
template <typename T>
class Combinatorics
{
private:
T mod;
T inv(T x)
{ // 快速幂求逆
return Math<T>::fastPow(x, mod - 2, mod);
}
void init(T N)
{ // 组合数计算初始化
fac[0] = 1;
for (T i = 1; i <= N; i++)
fac[i] = fac[i - 1] * i % mod;
}
public:
vector<T> fac; // 阶乘
Combinatorics(T N, T mod = 1e9 + 7) : mod(mod)
{
fac.assign(N + 1, 0);
init(N);
}
T C(T n, T m)
{ // 朴素组合数计算
if (m < 0 || n - m < 0)
return 0;
return fac[n] * inv(fac[m]) % mod * inv(fac[n - m]) % mod;
}
T lucas(T n, T m)
{ // 卢卡斯定理
return m == 0 ? 1 % mod : lucas(n / mod, m / mod) * C(n % mod, m % mod) % mod;
}
T Stirling2(ll n, ll m)
{ // 第二类斯特灵数:将一个有 n 个元素的集合分成 m 个非空的集合,求方案数。
if (m > n)
return 0; // n大于m
ll res = 0;
for (int i = 0; i <= m; i++)
{ // 通项公式
ll p = Math<T>::fastPow(i, n) * inv(fac[i]) % mod * inv(fac[m - i]) % mod;
if ((m - i) % 2)
res = (res + mod - p) % mod;
else
res = (res + p) % mod;
}
return res % mod;
}
};
template <class Info>
class SegmentTree
{ // 下标从 1 开始
#define l(p) (p << 1)
#define r(p) (p << 1 | 1)
protected:
int n;
vector<Info> info;
void init(int _n)
{
vector<Info> _now(_n + 1, Info());
init(_now);
}
void init(vector<Info>& _init)
{
n = _init.size() - 1;
info.assign(n << 2, Info()); // 为info开辟大小
auto build = [&](auto self, int p, int l, int r)
{
if (l == r)
{
info[p] = _init[l];
return;
}
int mid = l + r >> 1;
self(self, l(p), l, mid);
self(self, r(p), mid + 1, r);
pushup(p);
};
build(build, 1, 1, n);
}
void pushup(int p)
{
info[p] = info[l(p)] + info[r(p)];
}
public:
// 该模板在单点替换的题目中,运算符重载可能会出现一定错误,比如出现了 空值替换有值 (不必要的替换)
SegmentTree() : n(0) {};
SegmentTree(int _n)
{
init(_n);
}
SegmentTree(vector<Info>& _init)
{
init(_init);
}
template<typename Args> // 万能引用
void modify(int p, int pl, int pr, int x, Args&& v)
{
if (pl == pr)
{
// info[p] = v;
info[p].apply(v);
return;
}
int mid = pl + pr >> 1;
if (x <= mid)
modify(l(p), pl, mid, x, v);
else
modify(r(p), mid + 1, pr, x, v);
pushup(p);
}
void modify(int p, Info&& v)
{
modify(1, 1, n, p, forward<Info>(v)); // 完美转发
}
void modify(int p, Info& v)
{
modify(1, 1, n, p, forward<Info>(v)); // 完美转发
}
Info query(int L, int R, int p, int pl, int pr)
{
if (pl > R || pr < L)
return Info();
if (L <= pl && pr <= R)
return info[p];
int mid = pl + pr >> 1;
return query(L, R, l(p), pl, mid) + query(L, R, r(p), mid + 1, pr);
}
Info query(int L, int R)
{
return query(L, R, 1, 1, n);
}
#undef l(p)
#undef r(p)
};
template<class Info, class T>
class SegmentTree_BinarySearch : SegmentTree<Info> {
#define super SegmentTree<Info>
public:
SegmentTree_BinarySearch() : super::n(0) {};
SegmentTree_BinarySearch(int _n)
{
super::init(_n);
}
SegmentTree_BinarySearch(vector<Info>& _init)
{
super::init(_init);
}
int bin_search(int L, int R, const T& v);
void modify(int p, const Info& v = Info())
{
super::modify(p, v);
}
Info query(int L, int R)
{
return super::query(L, R);
}
#undef super
};
template <class Info, class Tag>
class LazySegmentTree
{
/* 该模板可能在直接相加的情况下比较好用,区间替换可能会出大大小小问题,这里写出区间替换模板
* 区间替换并求区间和板子
struct Tag {
ll newValue = 0;
bool f = 0; // 是否进行替换
Tag() {};
Tag(ll newValue, bool f = 0) :newValue(newValue), f(f) {};
void apply(Tag t) {
if (t.f) { // 这里很重要,因为这个板子初始化的时候就会调用 tag,所以这里上个 f 作为保险
f = 1;
newValue = t.newValue;
}
}
};
struct Info {
ll value = 0;
Info() {};
Info(ll value) :value(value) {};
void apply(Tag t, int len) {
if (t.f)
value = t.newValue * len;
}
};
Info operator+(Info a, Info b) {
Info c;
c.value = a.value + b.value;
return c;
}
void solve(int CASE)
{
int n; cin >> n;
auto a = vector<Info>(n + 1, Info());
fa(i, 1, n) {
ll now; cin >> now;
a[i].now = now;
}
// 初始化的时候自动会调用所有 Tag
MT::LazySegmentTree<Info, Tag> sg(a);
// 查看每个值
fa(i, 1, n) {
cout << sg.query(i, i).value << ' ';
}
cout << endl;
int q; cin >> q;
while (q--) {
ll l, r, x; cin >> l >> r >> x;
sg.modifyRange(l, r, Tag(x, 1));
// 查看更新后的每个值
fa(i, 1, n)
cout << sg.query(i, i).value << ' ';
cout << endl;
}
return;
}
*/
#define l(p) (p << 1)
#define r(p) (p << 1 | 1)
protected:
int n;
vector<Info> info;
vector<Tag> tag;
void init(int _n)
{
vector<Info> _now(_n + 1);
init(_now);
}
void init(vector<Info>& _init)
{
n = _init.size() - 1;
info.assign(n << 2, Info()); // 为info开辟大小
tag.assign(n << 2, Tag()); // 为tag开辟大小
auto build = [&](auto self, int p, int l, int r)
{
if (l == r)
{
info[p] = _init[l];
return;
}
int mid = l + r >> 1;
self(self, l(p), l, mid);
self(self, r(p), mid + 1, r);
pushup(p);
};
build(build, 1, 1, n);
}
void pushup(int p)
{
info[p] = info[l(p)] + info[r(p)];
}
void apply(int p, const Tag& v, int len)
{
info[p].apply(v, len);
tag[p].apply(v);
}
void pushdown(int p, int pl, int pr)
{ // 传入pl, pr计算区间长度
int mid = pl + pr >> 1;
apply(l(p), tag[p], mid - pl + 1);
apply(r(p), tag[p], pr - mid);
tag[p] = Tag(); // 设空
}
public:
LazySegmentTree() : n(0) {};
LazySegmentTree(int _n)
{
init(_n);
}
LazySegmentTree(vector<Info>& _init)
{
init(_init);
}
void modify(int p, int pl, int pr, int x, const Info& v = Info())
{ // 单点修改
if (pl == pr)
{
info[p] = v;
return;
}
int mid = pl + pr >> 1;
pushdown(p, pl, pr); // 传入pl, pr计算区间长度
if (x <= mid)
modify(l(p), pl, mid, x, v);
else
modify(r(p), mid + 1, pr, x, v);
pushup(p);
}
void modify(int p, const Info& v = Info())
{
modify(1, 1, n, p, v);
}
Info query(int L, int R, int p, int pl, int pr)
{
if (pl > R || pr < L)
return Info();
if (L <= pl && pr <= R)
return info[p];
int mid = pl + pr >> 1;
pushdown(p, pl, pr); // 传入pl, pr计算区间长度
return query(L, R, l(p), pl, mid) + query(L, R, r(p), mid + 1, pr);
}
Info query(int L, int R)
{
return query(L, R, 1, 1, n);
}
void modifyRange(int L, int R, int p, int pl, int pr, const Tag& v)
{ // 区间修改
if (pl > R || pr < L)
return;
if (L <= pl && pr <= R)
{
apply(p, v, pr - pl + 1); // 传入区间长度
return;
}
int mid = pl + pr >> 1;
pushdown(p, pl, pr); // 传入pl, pr计算区间长度
modifyRange(L, R, l(p), pl, mid, v);
modifyRange(L, R, r(p), mid + 1, pr, v);
pushup(p);
}
void modifyRange(int L, int R, const Tag& v)
{
return modifyRange(L, R, 1, 1, n, v);
}
#undef l(p)
#undef r(p)
};
template <class T>
class List
{
private:
vector<int> l, r;
map<T, int> pos;
int cnt = 1, tail = 0;
public:
vector<T> value;
List(int n = 2e5 + 10)
{ // 预留空间,默认2e6
value.assign(n * 10, 0);
l.assign(n * 10, 0);
r.assign(n * 10, 0);
}
void remove(int idx)
{
try
{
if (tail == 0)
throw runtime_error("list size is null");
if (idx > tail)
throw runtime_error("remove null pos");
}
catch (const std::exception& e)
{
cerr << e.what() << endl;
}
l[r[idx]] = l[idx];
r[l[idx]] = r[idx];
tail--;
}
void insert(int idx, T val)
{
value[cnt] = val;
pos[val] = cnt;
// 插入节点
l[cnt] = idx;
r[cnt] = r[idx];
l[r[idx]] = cnt;
r[idx] = cnt++;
tail++;
}
void push_back(T val)
{
value[cnt] = val;
pos[val] = cnt;
// 插入节点
l[cnt] = tail;
r[cnt] = r[tail];
l[r[tail]] = cnt;
r[tail] = cnt++;
tail++;
}
void print_all()
{
int k = tail;
for (int i = r[0]; k; i = r[i])
{
cout << value[i] << ' ';
k--;
}
}
};
template <typename T>
class ST
{
public:
static vector<T> Log2;
/* 构造 st 表前,先在类外定义 Log2,防止多次计算
template <typename T>
vector<T> ST<T>::Log2;
*/
ST(vector<T>& arr, int MAXN = 1e6 + 10)
{
// arr 从 1 开始
n = arr.size() - 1;
Min.assign(n + 1, vector<T>(21));
Max.assign(n + 1, vector<T>(21));
if (Log2.size() == 0) {
Log2.resize(MAXN);
log2_pre(MAXN);
}
build(arr);
}
T queryMin(int l, int r)
{ // 查询最小值
T s = Log2[r - l + 1];
return min(Min[l][s], Min[r - (1 << s) + 1][s]);
}
T queryMax(int l, int r)
{ // 查询最大值
T s = Log2[r - l + 1];
return max(Max[l][s], Max[r - (1 << s) + 1][s]);
}
private:
vector<vector<T>> Min, Max;
int n;
void log2_pre(int MAXN)
{ // 预处理log2
Log2[0] = -1;
for (int i = 1; i < MAXN; i++)
{
Log2[i] = Log2[i / 2] + 1;
}
}
void build(vector<T>& arr)
{ // 构建ST表
for (int i = 1; i <= n; i++)
{
Min[i][0] = Max[i][0] = arr[i];
}
for (int j = 1; j <= Log2[n]; j++)
{
for (int i = 1; i + (1 << j) - 1 <= n; i++)
{
Min[i][j] = min(Min[i][j - 1], Min[i + (1 << (j - 1))][j - 1]);
Max[i][j] = max(Max[i][j - 1], Max[i + (1 << (j - 1))][j - 1]);
}
}
}
};
template <typename T>
class BitTree
{ // 树状数组(优化的可操作前缀和)
public:
BitTree(int N)
{
n = N + 20;
t.assign(n, 0);
}
void update(T idx, const T& k)
{
for (T i = idx + 1; i <= n; i += lowbit(i))
t[i - 1] += k; // 运算符可改
}
T getsum(T idx)
{
T res = 0;
for (T i = idx + 1; i > 0; i -= lowbit(i))
res += t[i - 1]; // 运算符可改
return res;
}
T queryRange(int l, int r)
{
return getsum(r) - getsum(l - 1);
}
private:
vector<T> t; // 下标从0开始,实际上就是前缀和数组
int n;
T lowbit(T k) { return k & -k; }
};
class Manacher
{
public:
vector<int> lengths; // 以每个字符为中心的最长长度回文串的半径
int max_length = -1; // 最大回文长度
Manacher(string str)
{
int n = str.size();
init(str, n);
};
private:
void init(string str, int n)
{
// build
string s;
s.assign(n * 2 + 100, ' ');
str = ' ' + str;
int cnt = 0;
s[++cnt] = '~', s[++cnt] = '#';
for (int i = 1; i <= n; i++)
s[++cnt] = str[i], s[++cnt] = '#';
s[++cnt] = '!';
// solve
int mr = 0, mid = 0;
vector<int> p(n * 2 + 100);
for (int i = 2; i <= cnt - 1; i++)
{
if (i <= mr)
p[i] = min(p[mid * 2 - i], mr - i + 1);
else
p[i] = 1;
while (s[i - p[i]] == s[i + p[i]])
++p[i];
if (i + p[i] > mr)
mr = i + p[i] - 1, mid = i;
// 更新最大回文长度
max_length = max(max_length, p[i]);
// 放最大回文长度
if (s[i] != '#' && s[i] != '~' && s[i] != '!')
lengths.push_back(p[i] - 1);
}
max_length--;
}
};
class DoubleHashString
{
private:
#define ll long long
#define pll pair<long, long>
vector<ll> hs1, bs1, hs2, bs2;
// const int mod1 = 2147483647;
// const int mod2 = 1000000007;
// int generateRandomBase(int mod) {
// random_device rd;
// mt19937 gen(rd());
// uniform_int_distribution<> dis(1, mod - 1);
// return dis(gen);
// }
// const int base1 = generateRandomBase(mod1);
// const int base2 = generateRandomBase(mod2);
const int base1 = 233; // 第一个质数基数
const int base2 = 131; // 第二个质数基数
const ll mod1 = 1e9 + 13; // 第一个模数
const ll mod2 = 998244353; // 第二个模数
public:
// 初始化函数,预计算质数基数的幂次
DoubleHashString(const string& s)
{
// s 下标从 0 开始,l r 查询下标从 1 开始
int n = s.size();
hs1.resize(n + 1);
bs1.resize(n + 1);
hs2.resize(n + 1);
bs2.resize(n + 1);
hs1[0] = hs2[0] = 0;
bs1[0] = bs2[0] = 1;
for (int i = 1; i <= n; i++)
{
bs1[i] = (bs1[i - 1] * base1) % mod1;
bs2[i] = (bs2[i - 1] * base2) % mod2;
hs1[i] = (hs1[i - 1] * base1 + s[i - 1] - 'a' + 1) % mod1;
hs2[i] = (hs2[i - 1] * base2 + s[i - 1] - 'a' + 1) % mod2;
}
}
// 获取子串的双哈希值
pll get(int l, int r)
{
ll x = ((hs1[r] - hs1[l - 1] * bs1[r - l + 1]) % mod1 + mod1) % mod1;
ll y = ((hs2[r] - hs2[l - 1] * bs2[r - l + 1]) % mod2 + mod2) % mod2;
return make_pair(x, y);
}
#undef ll
#undef pll
};
class SingleHashString
{ // 自然溢出单哈希
private:
#define ull unsigned long long
vector<ull> hs, p;
const int base = 131;
public:
SingleHashString(string s)
{
// s 下标从 0 开始,l r 查询下标从 1 开始
hs.resize(s.size() + 10), p.resize(s.size() + 10);
s = ' ' + s;
p[0] = 1;
for (int i = 1; i < s.size(); i++)
{
hs[i] = hs[i - 1] * base + s[i] - 'a' + 1;
p[i] = p[i - 1] * base;
}
}
ull get(int l, int r)
{
return hs[r] - hs[l - 1] * p[r - l + 1];
}
#undef ull
};
template <class T>
class LCA
{
public:
vector<int> depth;
// vector<int>w; 树上边差分没准能用上,w[to] 表示 to 到其 fa 节点的边
LCA(int n, vector<vector<int>>& e)
{
f.assign(n + 10, vector<int>(31));
depth.assign(n + 10, 0);
// w.assign(n + 10, 0);
init(1, 0, e); // 邻接表
}
int lca(int x, int y)
{
if (depth[x] < depth[y])
swap(x, y);
// 后面进行x节点默认比y节点深
for (int i = 29; i >= 0; i--)
if (depth[x] - (1 << i) >= depth[y])
x = f[x][i];
if (x == y)
return x; // 特判:y就是原本x的祖宗
for (int i = 29; i >= 0; i--)
if (f[x][i] != f[y][i]) // 说明还没找到祖宗,更新a、b后接着跳
x = f[x][i], y = f[y][i];
return f[x][0];
}
private:
vector<vector<int>> f; // f[x][i]即x的第2^i个祖先 (31是倍增用的,最大跳跃为2^30)
void init(int now, int fa, vector<vector<int>>& e) // 邻接表
{
depth[now] = depth[fa] + 1;
f[now][0] = fa; // 第一个祖先
for (int i = 1; (1 << i) <= depth[now]; i++) // 求now的各个祖先
f[now][i] = f[f[now][i - 1]][i - 1];
for (int to : e[now])
{ // now这个的点的祖先都找完了,dfs处理别的点
if (to == fa)
continue;
init(to, now, e);
// w[to] = e[i].w;
}
}
};
template <const int T>
class ModInt
{
private:
const static int mod = T;
public:
int x;
ModInt(int x = 0) : x(x% mod) {}
ModInt(long long x) : x(int(x% mod)) {}
int val() { return x; }
ModInt operator+(const ModInt& a) const
{
int x0 = x + a.x;
return ModInt(x0 < mod ? x0 : x0 - mod);
}
ModInt operator-(const ModInt& a) const
{
int x0 = x - a.x;
return ModInt(x0 < 0 ? x0 + mod : x0);
}
ModInt operator*(const ModInt& a) const { return ModInt(1LL * x * a.x % mod); }
ModInt operator/(const ModInt& a) const { return *this * a.inv(); }
bool operator==(const ModInt& a) const { return x == a.x; };
bool operator!=(const ModInt& a) const { return x != a.x; };
void operator+=(const ModInt& a)
{
x += a.x;
if (x >= mod)
x -= mod;
}
void operator-=(const ModInt& a)
{
x -= a.x;
if (x < 0)
x += mod;
}
void operator*=(const ModInt& a) { x = 1LL * x * a.x % mod; }
void operator/=(const ModInt& a) { *this = *this / a; }
friend ModInt operator+(int y, const ModInt& a)
{
int x0 = y + a.x;
return ModInt(x0 < mod ? x0 : x0 - mod);
}
friend ModInt operator-(int y, const ModInt& a)
{
int x0 = y - a.x;
return ModInt(x0 < 0 ? x0 + mod : x0);
}
friend ModInt operator*(int y, const ModInt& a) { return ModInt(1LL * y * a.x % mod); }
friend ModInt operator/(int y, const ModInt& a) { return ModInt(y) / a; }
friend ostream& operator<<(ostream& os, const ModInt& a) { return os << a.x; }
friend istream& operator>>(istream& is, ModInt& t) { return is >> t.x; }
ModInt pow(long long n) const
{
ModInt res(1), mul(x);
while (n)
{
if (n & 1)
res *= mul;
mul *= mul;
n >>= 1;
}
return res;
}
ModInt inv() const
{
int a = x, b = mod, u = 1, v = 0;
while (b)
{
int t = a / b;
a -= t * b;
swap(a, b);
u -= t * v;
swap(u, v);
}
if (u < 0)
u += mod;
return u;
}
};
static int kmp(string& t, string& s)
{ // 在文本串 t 中找到模式串 s 出现的次数
// build
int nn = s.size();
vector<int> nt(nn);
for (int i = 1; i < nn; i++)
{
int j = nt[i - 1];
while (j > 0 && s[i] != s[j])
j = nt[j - 1];
if (s[i] == s[j])
j += 1;
nt[i] = j;
}
// kmp
int n = t.size(), m = s.size(), j = 0;
int last = -1e9, ans = 0;
for (int i = 0; i < n; i++)
{
while (j > 0 && t[i] != s[j])
j = nt[j - 1];
if (t[i] == s[j])
j += 1;
if (j == m)
{
int head = i - m + 1;
if (head >= last + m)
{
ans += 1;
last = head;
}
}
}
return ans;
}
class KMP
{
private:
vector<int> nt;
string s;
public:
// 在文本串 t 中找到模式串 s 出现的次数
// 存入模式串 s
KMP(string& s) : s(s)
{
int n = s.size();
nt.resize(n);
for (int i = 1; i < n; i++)
{
int j = nt[i - 1];
while (j > 0 && s[i] != s[j])
j = nt[j - 1];
if (s[i] == s[j])
j += 1;
nt[i] = j;
}
}
// 查询文本串 t
int kmp(string& t)
{
int n = t.size(), m = s.size(), j = 0;
int last = -1e9, ans = 0;
for (int i = 0; i < n; i++)
{
while (j > 0 && t[i] != s[j])
j = nt[j - 1];
if (t[i] == s[j])
j += 1;
if (j == m)
{
int head = i - m + 1;
if (head >= last + m)
{
ans += 1;
last = head;
}
}
}
return ans;
}
};
class ACAutomaton {
private:
int cnt = 1;
vector<int>in;
struct kkk {
int son[26] = { 0 }; // 子节点
int fail = 0; // 失败指针
int flag = 0; // 模式串起点
int ans = 0; // 当前节点匹配次数
void clear() {
memset(son, 0, sizeof(son));
fail = flag = ans = 0;
}
};
vector<kkk>trie; // Trie树
// 拓扑排序优化
void topu() {
queue<int>q;
for (int i = 1; i <= cnt; i++)
if (!in[i])q.push(i);
while (!q.empty()) {
int u = q.front();
q.pop();
output[trie[u].flag] = trie[u].ans; // 更新输出
int v = trie[u].fail;
in[v]--;
trie[v].ans += trie[u].ans;
if (!in[v])q.push(v);
}
}
int MAXN;
int ASCII_SIZE = 26;
public:
vector<int>Map; // 模式串下标 对应的 模式串起点的节点
vector<int>output; // 模式串起点的节点 对应的 模式串在文本串中出现的个数
// ASCII_SIZE : 26、52、128
ACAutomaton(int MAXN, int ASCII_SIZE = 26) :MAXN(MAXN), ASCII_SIZE(ASCII_SIZE),
in(MAXN + 10, 0), Map(MAXN + 10, 0), output(MAXN + 10, 0), trie(MAXN + 10) {}
void clear() { // ( 这个 clear 可能有些问题 )
for (int i = 0; i < MAXN + 5; i++) {
Map[i] = in[i] = output[i] = 0;
trie[i].clear();
}
}
// 插入模式串
void insert(string& s, int num) {
int u = 1, len = s.size();
for (int i = 0; i < len; i++) {
int v = s[i] - ((ASCII_SIZE <= 52) ? 'a' : 0);
if (!trie[u].son[v])trie[u].son[v] = ++cnt;
u = trie[u].son[v];
}
if (!trie[u].flag)trie[u].flag = num; // 模式串起点赋值
Map[num] = trie[u].flag;
}
// 构建失败指针
void getFail() {
queue<int>q;
for (int i = 0; i < ASCII_SIZE; i++)trie[0].son[i] = 1;
q.push(1);
while (!q.empty()) {
int u = q.front();
q.pop();
int Fail = trie[u].fail;
for (int i = 0; i < ASCII_SIZE; i++) {
int v = trie[u].son[i];
if (!v) {
trie[u].son[i] = trie[Fail].son[i];
continue;
}
trie[v].fail = trie[Fail].son[i];
in[trie[v].fail]++;
q.push(v);
}
}
}
// 查询文本串
void query(string& s) {
int u = 1, len = s.size();
for (int i = 0; i < len; i++)
u = trie[u].son[s[i] - ((ASCII_SIZE <= 52) ? 'a' : 0)], trie[u].ans++;
topu();
}
};
template<typename T>
class MinCostMaxFlow {
public:
// 边的结构体
struct Edge {
int to; // 目标节点
T cap; // 边的容量
T cost; // 边的费用
int rev; // 反向边在邻接表中的索引
};
// 构造函数,初始化节点数
MinCostMaxFlow(int n) : n(n), graph(n + 1), dist(n + 1), prevv(n + 1), preve(n + 1), h(n + 1) {}
// 添加边
void addEdge(int from, int to, T cap, T cost = 0) {
graph[from].push_back(Edge{ to, cap, cost, (int)graph[to].size() });
graph[to].push_back(Edge{ from, 0, -cost, (int)graph[from].size() - 1 });
}
// 计算最小费用最大流的函数
T minCostMaxFlow(int s, int t, T& flow) {
T res = 0; // 最小费用
fill(h.begin(), h.end(), 0); // 初始化势能数组
while (true) {
// 使用优先队列实现的Dijkstra算法
priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> pq;
fill(dist.begin(), dist.end(), INF); // 初始化距离数组
dist[s] = 0;
pq.push({ 0, s });
while (!pq.empty()) {
auto [d, v] = pq.top();
pq.pop();
if (dist[v] < d) continue;
for (int i = 0; i < graph[v].size(); ++i) {
Edge& e = graph[v][i];
if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
prevv[e.to] = v;
preve[e.to] = i;
pq.push({ dist[e.to], e.to });
}
}
}
if (dist[t] == INF) break; // 如果无法到达汇点,结束
for (int i = 0; i <= n; ++i) h[i] += dist[i]; // 更新势能
T d = INF;
for (int v = t; v != s; v = prevv[v]) {
d = min(d, graph[prevv[v]][preve[v]].cap); // 找到增广路径上的最小容量
}
flow += d; // 增加总流量
res += d * h[t]; // 增加总费用
for (int v = t; v != s; v = prevv[v]) {
Edge& e = graph[prevv[v]][preve[v]];
e.cap -= d; // 更新正向边的容量
graph[v][e.rev].cap += d; // 更新反向边的容量
}
}
return res; // 返回最小费用
}
private:
int n; // 节点数
const int INF = 1e9; // 定义无穷大
vector<vector<Edge>> graph; // 邻接表表示的图
vector<T> dist; // 最短路径费用
vector<int> prevv; // 前驱节点
vector<int> preve; // 前驱边
vector<T> h; // 势能数组
};
class XorBase {
private:
vector<long long> a; // 线性基基底
const int MN = 62;
bool flag = false;
public:
XorBase() :a(70, 0) {};
void print() {
for (int i : a)
cout << i << ' ';
cout << endl;
}
// XorBase[x]:说明第 x 位上存在代表性数 XorBase[x]
// 这个代表数的特点就是,最高位即为 2 ^ x
long long& operator[](int x) {
return a[x];
}
// 清除基底
void clear() {
a.clear();
}
// 插入新数
void insert(long long x) {
for (int i = MN; ~i; i--)
if (x & (1ll << i))
if (!a[i]) { a[i] = x; return; }
else x ^= a[i];
flag = true;
}
// 插入新数
void operator +=(long long x) {
insert(x);
}
// 线性基合并
void operator +=(XorBase& x) {
for (int i = MN; i >= 0; i--)if (x[i])*this += x[i];
}
friend XorBase operator +(XorBase& x, XorBase& y) {
XorBase z = x;
for (int i = 62; i >= 0; i--)if (y[i])z += y[i];
return z;
}
// 查是否存在线性基内
bool check(long long x) {
for (int i = MN; ~i; i--)
if (x & (1ll << i))
if (!a[i])return false;
else x ^= a[i];
return true;
}
// 查最大
long long qmax(long long res = 0) {
for (int i = MN; ~i; i--)
res = max(res, res ^ a[i]);
return res;
}
// 查最小
long long qmin() {
if (flag)return 0;
for (int i = 0; i <= MN; i++)
if (a[i])return a[i];
}
// 查询第 k 小
long long query(long long k) {
long long tmp[70] = { 0 };
long long res = 0; int cnt = 0;
k -= flag; if (!k)return 0;
for (int i = 0; i <= MN; i++) {
for (int j = i - 1; ~j; j--)
if (a[i] & (1ll << j))a[i] ^= a[j];
if (a[i])tmp[cnt++] = a[i];
}
if (k >= (1ll << cnt))return -1;
for (int i = 0; i < cnt; i++)
if (k & (1ll << i))res ^= tmp[i];
return res;
}
};
template<typename T>
class fast {
public:
// 使用 __int128 直接传入 T = __int128 就行
inline static T in()
{
T x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = x * 10 + ch - '0', ch = getchar();
return x * f;
}
static void out(T x)
{
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
out(x / 10);
putchar(x % 10 + '0');
return;
}
static void outln(T x)
{
out(x);
putchar('\n');
}
};
class PersistentSegmemtTree {
// 可持久化权值线段树(主席树)
// 可能需要离散化,根据离散化数组进行初始化
// 下标从 1 开始
/* 求第 k 小模板
int n, m; cin >> n >> m;
auto a = vector<int>(n + 1);
auto b = vector<int>();
fa(i, 1, n)cin >> a[i], b.pb(a[i]);
sort(all(b));
b.erase(unique(all(b)), b.end());
int len = b.size();
PersistentSegmemtTree sg(len, n);
auto find = [&](int value)->int {
return upper_bound(all(b), value) - b.begin();
};
// 初始化主席树,记得赋值
fa(i, 1, n) sg.root[i] = sg.update(find(a[i]), 1, sg.root[i - 1]);
while (m--) {
int l, r, k; cin >> l >> r >> k;
// 求区间相减,传入 l - 1
cout << b[sg.query_k_min(l - 1, r, k) - 1] << endl;
}
*/
/* 求区间多少不同元素模板
int n; cin >> n;
PersistentSegmemtTree sg(n, n);
HashMap<int, int>mp;
fa(i, 1, n) {
int x; cin >> x;
if (mp.count(x)) {
// 如果之前出现过,且出现在 mp[x] 位置,
// 就删掉之前出现的,转而把这个值放在现在的 i 上,
// 这样能保证每个线段树都存在这个数,同时也不会重复
int t = sg.update(mp[x], -1, sg.root[i - 1]);
sg.root[i] = sg.update(i, 1, t);
}
else sg.root[i] = sg.update(i, 1, sg.root[i - 1]);
mp[x] = i;
}
int m; cin >> m;
while (m--) {
int l, r; cin >> l >> r;
cout << sg.query(l, r) << endl;
}
*/
private:
int tot = 0;
struct tree { int l = 0, r = 0, sum = 0; };
vector<tree>t;
int len;
int build(int l, int r) { // 初始化建树,建 len 个节点的
int node = ++tot;
if (l == r)return node;
int mid = l + r >> 1;
t[node].l = build(l, mid);
t[node].r = build(mid + 1, r);
return node;
}
public:
vector<int>root;
// m 传入实际离散化后大小即可,不用 + 1
// n 传入离散化前的个数
PersistentSegmemtTree(int m, int n) :len(m), t((n << 6) + 10), root(n + 10) {
root[0] = build(1, len);
}
// 主席树的更新继承上一个线段树的根节点
int update(int l, int r, int pos, int value, int pre) {
int node = ++tot;
t[node] = t[pre];
t[node].sum += value;
if (l == r)return node;
int mid = l + r >> 1;
if (pos <= mid) // 新的左子节点会继承前一个版本的左子节点进行更新
t[node].l = update(l, mid, pos, value, t[pre].l);
else // 同理
t[node].r = update(mid + 1, r, pos, value, t[pre].r);
return node;
}
// 传入离散化数组对应的下标,更新的值,上一个已更新的线段树的根节点
int update(int pos, int value, int pre) {
return update(1, len, pos, value, pre);
}
// update 是加,change 是直接改变
int change(int l, int r, int pos, int value, int pre) {
int node = ++tot;
t[node] = t[pre];
t[node].sum = value;
if (l == r)return node;
int mid = l + r >> 1;
if (pos <= mid)
t[node].l = change(l, mid, pos, value, t[pre].l);
else
t[node].r = change(mid + 1, r, pos, value, t[pre].r);
return node;
}
int change(int pos, int value, int pre) {
return change(1, len, pos, value, pre);
}
// 本质其实是同时算两个权值线段树在 [1, l] 和 [1, r] 两个区间查询
int query_k_min(int u, int v, int l, int r, int k) {
int mid = l + r >> 1;
// 通过区间减法得左儿子中存的数值个数
int lnum = t[t[v].l].sum - t[t[u].l].sum;
if (l == r)return l;
if (k <= lnum) // 第 k 小在左子
return query_k_min(t[u].l, t[v].l, l, mid, k);
else // 第 k 小在右子,并注意相减
return query_k_min(t[u].r, t[v].r, mid + 1, r, k - lnum);
}
// 原理是前缀和,要传入 L - 1
int query_k_min(int L, int R, int k) {
return query_k_min(root[L], root[R], 1, len, k);
}
// 朴素区间查询,但只需要传入一棵树
int queryRange(int l, int r, int L, int R, int pre) {
if (L <= l and r <= R) return t[pre].sum;
int mid = l + r >> 1;
int res = 0;
if (L <= mid)res += queryRange(l, mid, L, R, t[pre].l);
if (R > mid)res += queryRange(mid + 1, r, L, R, t[pre].r);
return res;
}
// v 为线段树版本,注意这个版本必须大于等于 R
int queryRange(int L, int R, int v = -1) {
if (v == -1)v = root[R];
// 这里只会传入一个线段树版本然后接着朴素查询
return queryRange(1, len, L, R, v);
}
};
template<typename T = long long>
class Frac
{
private:
T abs(const T& x)const { return x < 0 ? -x : x; }
T gcd(const T& x, const T& y)const { return y ? gcd(y, x % y) : x; }
Frac reduce()
{
bool flag = 0;
if (a < 0 && b < 0) a = -a, b = -b;
if (a < 0) a = -a, flag = 1;
if (b < 0) b = -b, flag = 1;
T ggcd = gcd(a, b);
a /= ggcd;
b /= ggcd;
if (flag) a = -a;
return *this;
}
void swap() { std::swap(a, b); }
Frac _swap(const Frac& t)const { return Frac(t.b, t.a); }
T FastPow(T x, T p, T mod)const
{
T ans = 1, bas = x;
for (; p; bas = bas * bas % mod, p >>= 1)
if (p & 1) ans = ans * bas % mod;
return ans;
}
public:
T a, b;
Frac(T A = 0, T B = 1) { a = A, b = B; }
T to_inv(const T& mod = 1e9 + 7)const { return a * FastPow(b, mod - 2, mod) % mod; }
Frac abs()const { return Frac(abs(a), abs(b)); }
friend ostream& operator<<(ostream& out, const Frac& a) { out << a.a << ' ' << a.b; return out; }
Frac operator =(const Frac& t) { return a = t.a, b = t.b, t; }
bool operator ==(const Frac& t)const { Frac A(*this), B(t); return (A.reduce().a == B.reduce().a) && (A.b == B.b); }
bool operator !=(const Frac& t)const { Frac A(*this), B(t); return (A.a != B.a) || (A.b != B.b); }
bool operator >(const Frac& t)const { Frac A(*this), B(t); T ggcd = gcd(A.reduce().b, B.reduce().b); return B.b / ggcd * A.a > A.b / ggcd * B.a; }
bool operator <(const Frac& t)const { Frac A(*this), B(t); T ggcd = gcd(A.reduce().b, B.reduce().b); return B.b / ggcd * A.a < A.b / ggcd * B.a; }
bool operator >=(const Frac& t)const { Frac A(*this), B(t); T ggcd = gcd(A.reduce().b, B.reduce().b); return B.b / ggcd * A.a >= A.b / ggcd * B.a; }
bool operator <=(const Frac& t)const { Frac A(*this), B(t); T ggcd = gcd(A.reduce().b, B.reduce().b); return B.b / ggcd * A.a <= A.b / ggcd * B.a; }
Frac operator +(const Frac& t)const { T ggcd = gcd(b, t.b); return Frac(b / ggcd * t.a + t.b / ggcd * a, b / ggcd * t.b).reduce(); }
Frac operator +=(const Frac& t) { return *this = *this + t; }
Frac operator *(const Frac& t)const { return Frac(a * t.a, b * t.b).reduce(); }
Frac operator *=(const Frac& t) { return *this = *this * t; }
Frac operator -(const Frac& t)const { return (*this + Frac(-t.a, t.b)).reduce(); }
Frac operator -=(const Frac& t) { return *this = *this - t; }
Frac operator /(const Frac& t)const { return (t._swap(t) * (*this)).reduce(); }
Frac operator /=(const Frac& t) { return *this = *this / t; }
Frac operator -()const { return Frac(-a, b); }
};
//////// CalGeo ////////
template<typename T>
class Point;
template<typename T>
class Line;
template<typename T>
class Polygon;
template<typename T>
class Circle;
template<typename T>
using Vector = Point<T>;
template<typename T>
using Segment = Line<T>;
namespace Geo {
const double eps = 1e-8;
const double PI = acos(-1.0);
// 浮点数 x 的符号
template<typename T>
int sgn(T x) {
if (fabs(x) < eps) return 0;
return x > 0 ? 1 : -1;
}
// 比较两个浮点数
template<typename T>
int cmp(T x, T y) {
if (fabs(x) < eps)return 0; // x == y,返回 0
else return x < y ? -1 : 1; // x < y,返回 -1; x > y,返回 1
}
// 两点距离
template<typename T>
T dist(const Point<T>& A, const Point<T>& B) {
return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}
// 点积
template<typename T>
T dot(const Vector<T>& A, const Vector<T>& B) {
return A.x * B.x + A.y * B.y;
}
// 叉积
template<typename T>
T cross(const Vector<T>& A, const Vector<T>& B) {
return A.x * B.y - A.y * B.x;
}
// 向量长度
template<typename T>
T len(const Vector<T>& A) {
return sqrt(dot(A, A));
}
// 向量长度的平方
template<typename T>
T len2(const Vector<T>& A) {
return dot(A, A);
}
// 两向量夹角
template<typename T>
double angle(const Vector<T>& A, const Vector<T>& B) {
return acos(dot(A, B) / len(A) / len(B));
}
// 计算两向量构成的平行四边形有向面积
// 三个点A、B、C,以A为公共点,得到2个向量B-A和C-A,它们构成的平行四边形
template<typename T>
T area2(const Point<T>& A, const Point<T>& B, const Point<T>& C) {
return cross(B - A, C - A);
}
// 向量旋转
/*
特殊情况是旋转90度:
逆时针旋转90度:Rotate(A, pi/2),返回Vector(-A.y, A.x);
顺时针旋转90度:Rotate(A, -pi/2),返回Vector(A.y, - A.x)。
*/
template<typename T>
Vector<T> rotate(const Vector<T>& A, double rad) {
return Vector<T>(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad));
}
// 有时需要求单位法向量,即逆时针转90度,然后取单位值。
template<typename T>
Vector<T> normal(const Vector<T>& A) {
return Vector<T>(-A.y / len(A), A.x / len(A));
}
// 两个向量是否平行或重合
template<typename T>
bool parallel(const Vector<T>& A, const Vector<T>& B) {
return sgn(cross(A, B)) == 0; // 返回true表示平行或重合
}
// 点和直线的位置关系
template<typename T>
int point_line_relation(const Point<T>& p, const Line<T>& v) {
int c = sgn(cross(p - v.p1, v.p2 - v.p1));
if (c < 0)return 1; // 1 :p在v的左边
if (c > 0)return 2; // 2 :p在v的右边
return 0; // 0 :p在v上
}
// 点和线段的位置关系
template<typename T>
bool point_is_on_segment(const Point<T>& p, const Line<T>& v) { // 点和线段:0 点不在线段v上;1 点在线段v上
return sgn(cross(p - v.p1, v.p2 - v.p1)) == 0 && sgn(dot(p - v.p1, p - v.p2)) <= 0;
}
// 点到直线的距离
template<typename T>
double point_line_dis(const Point<T>& p, const Line<T>& v) {
return fabs(cross(p - v.p1, v.p2 - v.p1)) / dist(v.p1, v.p2);
}
// 点在直线上的投影
template<typename T>
Point<T> point_line_proj(const Point<T>& p, const Line<T>& v) {
double k = dot(v.p2 - v.p1, p - v.p1) / Len2(v.p2 - v.p1);
return v.p1 + (v.p2 - v.p1) * k;
}
// 点关于直线的对称点
template<typename T>
Point<T> point_line_symmetry(const Point<T>& p, const Line<T>& v) {
Point<T> q = point_line_proj(p, v);
return Point<T>(2 * q.x - p.x, 2 * q.y - p.y);
}
// 点到线段的距离
template<typename T>
double point_segment_dis(const Point<T>& p, const Segment<T>& v) {
if (sgn(dot(p - v.p1, v.p2 - v.p1)) < 0 || sgn(dot(p - v.p2, v.p1 - v.p2)) < 0)
return min(dist(p, v.p1), dist(p, v.p2));
return point_line_dis(p, v); // 点的投影在线段上
}
// 叉积判断两条向量的位置关系,AB * AC,两向量共点
template<typename T>
int vector_vector_relation(const Vector<T>& v1, const Vector<T>& v2) {
int sign = sgn(cross(v1, v2));
if (sign == 0)return 0; // 共线
if (sign > 0)return 1; // v2 在 v1 的逆时针方向
if (sign < 0)return 2; // v2 在 v1 的顺时针方向
}
// 叉积判断两条直线的位置关系
template<typename T>
int line_line_relation(const Line<T>& v1, const Line<T>& v2) {
if (sgn(cross(v1.p2 - v1.p1, v2.p2 - v2.p1)) == 0) {
if (point_line_relation(v1.p1, v2) == 0) return 1; // 1: 重合
else return 0; // 0: 平行
}
return 2; // 2: 相交
}
// 两条直线的交点
template<typename T>
Point<T> line_line_cross_point(const Point<T>& a, const Point<T>& b, const Point<T>& c, const Point<T>& d) {
// Line1 : ab, Line2 : cd
double s1 = cross(b - a, c - a);
double s2 = cross(b - a, d - a); // 叉积有正负
return Point<T>(c.x * s2 - d.x * s1, c.y * s2 - d.y * s1) / (s2 - s1);
}
// 两个线段是否相交
template<typename T>
bool segment_segment_is_cross(const Point<T>& a, const Point<T>& b, const Point<T>& c, const Point<T>& d) {
// Line1 : ab, Line2 : cd
double c1 = cross(b - a, c - a), c2 = cross(b - a, d - a);
double d1 = cross(d - c, a - c), d2 = cross(d - c, b - c);
return sgn(c1) * sgn(c2) < 0 && sgn(d1) * sgn(d2) < 0; // 1: 相交;0: 不相交
}
// 点和多边形的关系
template<typename T>
int point_polygon_relation(const Point<T>& pt, const Polygon<T>& p) {
// 点pt,多边形 p
int n = p.size();
for (int i = 0; i < n; i++) {
if (p[i] == pt) return 3; // 3:点在多边形的顶点上
}
for (int i = 0; i < n; i++) {
Line<T> v = Line<T>(p[i], p[(i + 1) % n]);
if (point_is_on_segment(pt, v)) return 2; // 2:点在多边形的边上
}
int num = 0;
for (int i = 0; i < n; i++) {
int j = (i + 1) % n;
int c = sgn(cross(pt - p[j], p[i] - p[j]));
int u = sgn(p[i].y - pt.y);
int v = sgn(p[j].y - pt.y);
if (c > 0 && u < 0 && v >= 0) num++;
if (c < 0 && u >= 0 && v < 0) num--;
}
return num != 0; // 1:点在内部; 0:点在外部
}
// 计算多边形周长
template<typename T>
T polygon_perimeter(const Polygon<T>& p) {
T ans = 0;
int n = p.size();
for (int i = 0; i < n; i++)
ans += dist(p[i], p[(i + 1) % n]);
return ans;
}
// 多边形的面积
template<typename T>
T polygon_area(const Polygon<T>& p) {
T area = 0;
int n = p.size();
for (int i = 0; i < n; i++)
area += cross(p[i], p[(i + 1) % n]);
return area / 2; // 面积有正负,返回时不能简单地取绝对值
}
// 多边形的重心
template<typename T>
Point<T> polygon_center_point(const Polygon<T>& p) { //求多边形重心
Point<T> ans(0, 0);
int n = p.size();
if (polygon_area(p, n) == 0) return ans;
for (int i = 0; i < n; i++)
ans = ans + (p[i] + p[(i + 1) % n]) * cross(p[i], p[(i + 1) % n]);
return ans / polygon_area(p, n) / 6;
}
// 求凸包,凸包顶点放在ch中
// 凸多边形:是指所有内角大小都在 [0, 180] 范围内的简单多边形
// 凸包:在平面上能包含所有给定点的最小凸多边形叫做凸包
template<typename T>
Polygon<T> convex_hull(const vector<Point<T>>& p) {
Polygon<T> ch;
int n = p.size();
n = unique(p.begin(), p.end()) - p; // 去除重复点
ch.resize(n);
sort(p.begin(), p.begin() + n); // 对点排序:按 x 从小到大排序,如果 x 相同,按 y 排序
int v = 0;
// 求下凸包,如果p[i]是右拐弯的,这个点不在凸包上,往回退
for (int i = 0; i < n; i++) {
while (v > 1 && sgn(cross(ch[v - 1] - ch[v - 2], p[i] - ch[v - 1])) <= 0) // 把后面 ch[v-1] 改成 ch[v-2] 也行
v--;
ch[v++] = p[i];
}
int j = v;
// 求上凸包
for (int i = n - 2; i >= 0; i--) {
while (v > j && sgn(cross(ch[v - 1] - ch[v - 2], p[i] - ch[v - 1])) <= 0) // 把后面 ch[v-1] 改成 ch[v-2] 也行
v--;
ch[v++] = p[i];
}
ch.erase(unique(ch.begin(), ch.end()), ch.end());
return ch;
}
// 点和圆的关系,根据点到圆心的距离判断
template<typename T>
int point_circle_relation(const Point<T>& p, const Circle<T>& C) {
double dst = dist(p, C.c);
if (sgn(dst - C.r) < 0) return 0; // 0: 点在圆内
if (sgn(dst - C.r) == 0) return 1; // 1: 圆上
return 2; // 2: 圆外
}
// 直线和圆的关系,根据圆心到直线的距离判断
template<typename T>
int line_circle_relation(const Line<T>& v, const Circle<T>& C) {
double dst = point_line_dis(C.c, v);
if (sgn(dst - C.r) < 0) return 0; // 0: 直线和圆相交
if (sgn(dst - C.r) == 0) return 1; // 1: 直线和圆相切
return 2; // 2: 直线在圆外
}
// 线段和圆的关系,根据圆心到线段的距离判断
template<typename T>
int segment_circle_relation(const Segment<T> v, const Circle<T> C) {
double dst = point_segment_dis(C.c, v);
if (sgn(dst - C.r) < 0) return 0; // 0: 线段在圆内
if (sgn(dst - C.r) == 0) return 1; // 1: 线段和圆相切
return 2; // 2: 线段在圆外
}
//pa, pb是交点。返回值是交点个数
template<typename T>
int line_cross_circle(const Line<T>& v, const Circle<T>& C, Point<T>& p1, Point<T>& p2) {
if (line_circle_relation(v, C) == 2) return 0; // 无交点
Point<T> q = point_line_proj(C.c, v); // 圆心在直线上的投影点
double d = point_line_dis(C.c, v); // 圆心到直线的距离
double k = sqrt(C.r * C.r - d * d);
if (sgn(k) == 0) { // 1个交点,直线和圆相切
p1 = q; p2 = q; return 1;
}
Point<T> n = (v.p2 - v.p1) / len(v.p2 - v.p1); // 单位向量
p1 = q + n * k; p2 = q - n * k;
return 2; // 2个交点
}
};
template<typename T>
class Point {
public:
T x, y;
Point(T x = 0, T y = 0) : x(x), y(y) {}
// 向量长度
T len() {
return sqrt(len2());
}
// 向量长度的平方
T len2() {
return (*this) * (*this);
}
Point operator- (const Point& B) const { return Point(x - B.x, y - B.y); }
Point operator+ (const Point& B) const { return Point(x + B.x, y + B.y); }
T operator^ (const Point<T>& B) const { return x * B.y - y * B.x; } // 叉积
T operator* (const Point<T>& B) const { return x * B.x + y * B.y; } // 点积
Point operator* (const T& B) const { return Point(x * B, y * B); }
Point operator/ (const T& B) const { return Point(x / B, y / B); }
bool operator< (const Point& B) const { return x < B.x || (x == B.x && y < B.y); }
bool operator> (const Point& B) const { return x > B.x || (x == B.x && y > B.y); }
bool operator== (const Point& B) const { return Geo::sgn(x - B.x) == 0 && Geo::sgn(y - B.y) == 0; }
bool operator!= (const Point& B) const { return Geo::sgn(x - B.x) || Geo::sgn(y - B.y); }
friend ostream& operator<<(ostream& out, const Point& a) { out << '(' << a.x << ',' << a.y << ')'; return out; }
};
template<typename T>
class Line {
public:
Point<T> p1, p2; // 线上的两个点
Line() {}
Line(Point<T> p1, Point<T> p2) :p1(p1), p2(p2) {}
Line(Point<T> p, double angle) { // 根据一个点和倾斜角 angle 确定直线,0 <= angle < pi
p1 = p;
if (Geo::sgn(angle - Geo::PI / 2) == 0) { p2 = (p1 + Point<T>(0, 1)); }
else { p2 = (p1 + Point<T>(1, tan(angle))); }
}
Line(double a, double b, double c) { // ax + by + c = 0
if (Geo::sgn(a) == 0) {
p1 = Point<T>(0, -c / b);
p2 = Point<T>(1, -c / b);
}
else if (Geo::sgn(b) == 0) {
p1 = Point<T>(-c / a, 0);
p2 = Point<T>(-c / a, 1);
}
else {
p1 = Point<T>(0, -c / b);
p2 = Point<T>(1, (-c - a) / b);
}
}
friend ostream& operator<<(ostream& out, const Point<T>& a) { out << a.x << ',' << a.y; return out; }
};
template<typename T>
class Polygon : public vector<Point<T>> {
public:
Polygon(int n) :vector<Point<T>>(n) {};
friend ostream& operator<<(ostream& out, const Polygon<T>& a) {
for (auto& i : a)
out << i << ' ';
return out;
}
};
template<typename T>
class Circle {
public:
Point<T> c; // 圆心
T r; // 半径
Circle() {}
Circle(Point<T> c, T r) :c(c), r(r) {}
Circle(T x, T y, T _r) { c = Point<T>(x, y); r = _r; }
friend ostream& operator<<(ostream& out, const Circle<T>& a) {
out << a.c << ',' << a.r;
return out;
}
};
////////////////////////
}
namespace MT = MyTools;
using Math = MT::Math<ll>;
using mint = MT::ModInt<998244353>;
const int mod = 1e9 + 7;
const int N = 1e6 + 10;
void solve(int CASE)
{
int r, c; cin >> r >> c;
var a = vector<string>(r + 1);
fa(i, 1, r)cin >> a[i], a[i] = ' ' + a[i];
// 扩展域并查集
var s = vector<int>(2 * r + 1);
fa(i, 1, 2 * r)s[i] = i;
// 每列出现 1 的各个行
var g = vector<vector<int>>(c + 1);
fa(i, 1, r)
fa(j, 1, c)
if (a[i][j] == '1')
g[j].pb(i);
var find = [&](var find, int x)->int {
if (x != s[x])return s[x] = find(find, s[x]);
return s[x];
};
var merge = [&](int x, int y)->void {
s[find(find, y)] = find(find, x);
};
// 中心的怎么翻转都没用了
if (c % 2 == 1 and g[(c + 1) / 2].size() > 1) {
cout << 0 << endl;
return;
}
fa(i, 1, c / 2) { // 枚举列
var j = c - i + 1;
var tot = g[i].size() + g[j].size();
// 这列和对称列 1 的个数不能大于 2
if (tot > 2) {
cout << 0 << endl;
return;
}
if (tot <= 1)continue;
if (g[i].size() == 2) {
merge(g[i][0], g[i][1] + r);
merge(g[i][1], g[i][0] + r);
}
else if (g[j].size() == 2) {
merge(g[j][0], g[j][1] + r);
merge(g[j][1], g[j][0] + r);
}
else {
merge(g[i][0], g[j][0]);
merge(g[i][0] + r, g[j][0] + r);
}
}
fa(i, 1, r) {
if (s[find(find, i)] == s[find(find, i + r)]) {
cout << 0 << '\n';
return;
}
}
int ans = 0;
fa(i, 1, 2 * r)ans += (s[i] == i);
cout << Math::fastPow(2, ans / 2, mod) << endl;
return;
}
int main()
{
//SetConsoleOutputCP(CP_UTF8);
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
cin >> _;
fa(i, 1, _)solve(i);
return 0;
}
这程序好像有点Bug,我给组数据试试?
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3540kb
input:
3 3 5 01100 10001 00010 2 1 1 1 2 3 001 001
output:
4 0 2
result:
ok 3 number(s): "4 0 2"
Test #2:
score: 0
Accepted
time: 10ms
memory: 3848kb
input:
15613 10 10 0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 0000000000 15 8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1 5 00000 5 9 000000000 000000000 0000...
output:
1024 32768 2 32 32768 128 32 16 16 2 16384 16384 128 128 32768 8192 128 64 16384 2 4 2 4096 16 4096 1024 32768 32768 16384 8 128 2 16 4096 8192 32768 8192 8192 16 16384 16384 256 128 8 256 8 4096 512 2 4 32 32 2 64 512 1024 32768 32768 2 64 16384 16 8192 16 256 16 64 8192 8192 64 1024 2 32768 2 4 51...
result:
ok 15613 numbers
Test #3:
score: 0
Accepted
time: 11ms
memory: 3844kb
input:
15759 9 6 000000 000000 000000 000000 000000 000000 000000 000000 000000 5 15 010000000000000 000000000000000 000000000000000 000100000000000 000100000000000 14 12 000000000000 000000000000 000000000000 000000000000 000000000000 000000000000 000000000000 000000000000 000000000000 000000000000 000000...
output:
512 16 16384 512 1024 4096 32768 4 2 512 512 512 512 8 2 256 16 4096 512 64 16 4096 512 32 32768 8192 32 2048 128 16 4096 64 32768 256 32 16384 8 512 32 2048 8 16 1024 2048 128 64 32 8 512 8 8192 256 8192 32768 2 8 512 512 256 32 2 2048 8192 8 64 8 2 16384 32768 32768 1024 4096 16384 16384 128 256 4...
result:
ok 15759 numbers
Test #4:
score: 0
Accepted
time: 15ms
memory: 3844kb
input:
15734 3 6 000101 010000 001110 5 7 0010010 1000000 0101000 0000000 0000000 10 9 000000000 100000000 000000000 000000000 000010000 000000001 000000000 000000000 000000000 000000000 5 14 10000000000000 00001001000000 00000100000000 00000000000000 00000100000000 5 14 00000000000000 00010000000100 00000...
output:
0 16 512 16 32 4096 0 256 0 0 0 0 4096 8 1024 128 8192 0 128 0 2 0 0 32 64 0 0 0 4096 64 8 8 32 128 64 4096 2 512 16384 4 2 0 0 32 0 4096 8 0 8192 256 256 64 0 32 0 32 0 256 4 16384 1024 4 0 16 256 0 2048 64 8 0 0 32768 2048 512 2048 2 0 8192 0 2 2048 16 512 256 1024 0 0 2 32 512 16384 0 32 1024 102...
result:
ok 15734 numbers
Test #5:
score: 0
Accepted
time: 15ms
memory: 3796kb
input:
15616 14 3 000 000 000 000 100 000 000 000 000 000 001 001 001 000 15 5 00000 00000 00010 00000 00000 01000 00000 00000 00000 00001 00100 00000 00000 00000 10000 9 14 00000000000000 00000000000000 00100000010000 00001000100000 01010010000010 00000000000000 01000000000010 00100011000001 0000000000000...
output:
0 8192 0 64 0 512 0 8192 0 512 0 0 64 0 0 256 0 512 0 0 16 0 2048 0 256 0 1024 0 0 2 2 0 64 32 0 2 2 512 16 0 2 4 8192 0 0 1024 256 8 0 32 4 0 0 0 0 0 1024 4096 0 16384 32 0 2 4096 2 512 0 0 0 64 0 0 0 0 2 0 128 256 16 2 128 0 8 2 16384 0 0 2 0 0 0 128 0 0 0 0 0 2 4096 512 0 0 2 0 256 0 2 0 0 0 8 0 ...
result:
ok 15616 numbers
Test #6:
score: 0
Accepted
time: 16ms
memory: 3800kb
input:
15525 5 1 1 0 0 0 0 14 15 000000000000000 000001000010000 000000000000000 000000000000000 000110000000000 000000000000001 000000000000000 000010000010000 000000000000000 001010000000000 000101000000000 000000000000100 000000000000000 000100010001000 14 15 000000000000000 000000000000000 000000000010...
output:
32 0 0 0 0 0 0 2 2 16384 0 0 0 2 0 0 0 0 32 0 2048 0 0 256 4096 0 0 512 0 0 0 0 16 0 0 0 0 0 0 0 1024 0 0 0 0 0 0 0 0 0 128 0 0 0 512 0 0 0 0 2 8 0 0 0 16 1024 0 0 0 32 8192 0 0 0 0 0 4 0 0 0 128 4 0 0 2048 0 0 2 32768 0 0 4096 0 2 0 0 0 8 2 0 0 0 0 32 0 0 0 0 0 2 0 8192 4096 0 0 0 0 512 0 0 0 4 0 0...
result:
ok 15525 numbers
Test #7:
score: 0
Accepted
time: 19ms
memory: 3844kb
input:
15547 5 7 1001011 0011001 1101011 0011011 0101011 3 14 11110100111110 01110111011111 11011111110111 4 4 1100 1110 0110 0101 9 9 000000000 101000100 001100100 100001000 000000010 100100000 010110000 000100110 110100000 5 8 10000001 10101011 11101010 01011110 10100111 12 12 000000100000 000000000010 0...
output:
0 0 0 0 0 0 2 0 0 0 0 0 16 0 2 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 2 0 0 0 0 0 0 0 0 0 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 2 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 ...
result:
ok 15547 numbers
Test #8:
score: 0
Accepted
time: 17ms
memory: 3612kb
input:
15626 8 11 10000010011 01100000010 00000100010 10000010000 00001000000 10100000100 00101010011 00000011000 11 12 101000001000 000010010100 010001100001 000110101010 100010100000 100010000100 001100100000 010000100111 000011011101 000110010000 000000000000 15 8 00001000 00000000 00000000 00100000 000...
output:
0 0 0 2 0 1024 0 0 0 0 0 0 0 0 512 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 16 0 32768 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4096 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1024 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 15626 numbers
Test #9:
score: 0
Accepted
time: 13ms
memory: 3844kb
input:
15537 5 1 0 0 0 1 0 10 6 000000 000000 000010 000000 000000 000100 000000 100000 000000 000000 8 3 001 010 000 000 000 000 000 000 3 15 000000001000000 000010000000110 000000000000000 11 3 000 000 000 100 000 000 000 000 000 000 010 1 12 000000110100 3 7 0000010 0000001 0010000 8 1 0 0 0 0 1 0 0 0 1...
output:
32 1024 256 8 2048 2 8 256 2048 64 16384 32 8 4 2048 256 2048 8 32 128 16 32768 256 4096 256 64 2 128 8192 64 16 32768 64 8 1024 128 4096 32 4 16 4 2 8 128 2 1024 2048 1024 16384 256 128 1024 64 512 2048 1024 256 64 32 32 2048 4096 1024 32768 4 4096 256 1024 8 8192 64 16384 2048 2048 16384 8 8192 16...
result:
ok 15537 numbers
Test #10:
score: 0
Accepted
time: 14ms
memory: 3844kb
input:
15581 4 4 0010 0001 0000 0000 9 14 00000000000000 00000000010000 00000000000000 10000001000000 00000100000010 00010000000000 00000000000000 00000000001000 00000000000100 6 11 00000000000 00000001000 01001000100 00000000000 00000000000 00000100001 14 13 0000000010001 0000000000000 0000000000000 00100...
output:
16 256 64 16384 16 32 32 64 16384 16384 2 16384 8 8192 8192 4096 128 32768 2 32 128 2048 32 32768 4096 2048 128 8 32768 256 256 16 256 4096 4 32768 4 16384 4 4 128 8192 4096 8192 2 8192 4096 2048 16384 1024 512 64 512 4096 2048 1024 2048 1024 8 16 16 1024 8 32 2 2048 1024 1024 16384 16384 64 512 512...
result:
ok 15581 numbers
Test #11:
score: 0
Accepted
time: 16ms
memory: 3560kb
input:
15614 12 9 000000001 000000100 000000000 000000000 000000000 000000000 000000010 010010000 000000000 000100000 000000100 000000001 5 5 01010 00000 10100 00000 00001 15 6 000000 000000 000000 000000 011001 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 2 7 1100000 0110001 13 5 ...
output:
512 16 32768 0 4096 0 16384 2 8 8192 32 4 1024 0 16 8 4 64 0 2 2 2 1024 128 128 128 2 32 1024 32 1024 16 64 64 128 1024 512 0 4096 2 32 1024 4096 256 4 2 4096 2 32 64 2 2 0 0 128 16 16 16 4096 1024 2048 16 256 16 16 64 0 1024 0 4096 2 2 16 4 4 8192 1024 512 0 256 2 8 128 128 64 16 128 4096 64 1024 2...
result:
ok 15614 numbers
Test #12:
score: 0
Accepted
time: 17ms
memory: 3632kb
input:
15569 11 3 000 000 000 000 000 000 100 000 000 010 000 2 11 00010000100 11000001101 7 13 0000000000010 0000000100000 1010010000000 0000001001000 0100000000100 1000100000000 0000100000000 12 6 000100 000001 000000 000000 000000 010000 000001 000000 000010 000100 000000 000000 9 6 000000 001000 000010...
output:
2048 0 4 512 64 16384 512 1024 4096 32 256 16 16384 0 512 8192 4096 4 128 4 8 512 1024 8 0 4096 4 4 128 2 4 64 4 512 128 64 16 0 4096 128 1024 0 4 2 0 16 64 256 1024 2048 256 0 4 8 8 16 256 512 256 0 2 2 2048 256 512 2048 4096 512 2048 16 0 1024 4 16 2 8192 1024 32 4 1024 256 32 4096 32 16 32 128 12...
result:
ok 15569 numbers
Test #13:
score: 0
Accepted
time: 17ms
memory: 3768kb
input:
15535 9 13 0000100000001 0000000000100 0000000000000 1000000100010 0000001000000 0001000000000 0000000000000 0000000000010 0001000000000 8 11 00000100100 00000000000 01000000000 10001000100 00010001000 10000000000 00000010000 01000000000 5 13 1000100000000 0001000010110 0000000100000 0001000100110 0...
output:
64 16 2 16384 2 8 8 8 2048 4096 0 256 0 4096 0 0 2 2 128 1024 16384 4 512 8 512 0 1024 2048 32 16 4 4096 0 8 2048 4 256 4 64 4 0 128 8192 4096 512 2 64 8 1024 8 8 16 32 1024 16 1024 1024 8192 4 16384 0 4 256 2 64 8192 2 2 16 8192 0 64 16 0 8 0 2 4096 64 0 32 128 2 2 2 8 0 32 16 16384 2048 64 1024 4 ...
result:
ok 15535 numbers
Test #14:
score: 0
Accepted
time: 17ms
memory: 3552kb
input:
15665 15 14 00000100100000 00000000001000 00000000000000 00001001000000 00000000000000 00000000000000 11000000000000 00000000000000 01000000000100 00000000000100 00000000000000 00000000000000 00000000000000 00000000010000 00000001001000 3 13 0010000010110 1101000100001 0001010000000 6 6 000100 00000...
output:
1024 0 32 2 256 256 4096 0 16384 16 64 16 256 2 2 0 256 2048 128 2 2048 2 8 2 2 4096 64 2 8 1024 0 128 512 64 512 64 128 4 256 16 128 16 2 4096 32 32 2 0 0 256 32 2 128 64 256 512 0 2 1024 0 0 512 4096 4 1024 0 8192 2 512 2048 64 0 0 64 0 32768 128 2 2048 512 16384 32 0 8 2 1024 2048 2 2048 4096 2 8...
result:
ok 15665 numbers
Test #15:
score: 0
Accepted
time: 3ms
memory: 4072kb
input:
68 835 480 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
output:
0 0 0 0 0 524288 0 0 0 0 524288 0 0 0 0 0 0 0 0 262144 262144 0 262144 524288 1048576 131072 262144 262144 0 262144 0 0 524288 0 0 0 524288 0 0 65536 0 1048576 131072 524288 131072 0 131072 131072 0 0 131072 0 0 262144 0 65536 0 131072 0 0 0 0 262144 262144 0 0 524288 0
result:
ok 68 numbers
Test #16:
score: 0
Accepted
time: 3ms
memory: 4248kb
input:
45 249 416 0000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 262144 0 0 0 0 131072 0 0 262144 131072 262144 262144 0 0 0 0 0 0 0
result:
ok 45 numbers
Test #17:
score: 0
Accepted
time: 3ms
memory: 4520kb
input:
59 60 930 00000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 65536 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
result:
ok 59 numbers
Test #18:
score: 0
Accepted
time: 0ms
memory: 4016kb
input:
58 902 434 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
output:
716352531 0 0 373675883 16384 190350546 0 0 0 32768 16384 8192 32768 32768 306437691 0 8192 68717736 8192 16384 8192 2048 8192 4096 8192 16384 0 8192 4096 8192 32768 4096 32768 131072 32768 8192 639816142 16384 8192 32768 0 1024 16384 4096 8192 16384 8192 8192 32768 16384 8192 4096 16384 8192 8192 8...
result:
ok 58 numbers
Test #19:
score: 0
Accepted
time: 3ms
memory: 4400kb
input:
36 672 226 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000...
output:
336127736 0 671371099 4096 8192 2048 0 224303060 475920650 16384 4096 8192 16384 2048 2048 2048 8192 4096 4096 8192 16384 4096 8192 16384 0 0 8192 8192 4096 4096 16384 4096 8192 8192 8192 2048
result:
ok 36 numbers
Test #20:
score: 0
Accepted
time: 3ms
memory: 4080kb
input:
12 73 749 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000100000001000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000...
output:
0 653145782 310559811 835685553 16384 0 0 4096 884119779 1024 4096 1024
result:
ok 12 numbers
Test #21:
score: 0
Accepted
time: 7ms
memory: 7268kb
input:
1 50000 20 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 0000000000000000...
output:
188635342
result:
ok 1 number(s): "188635342"
Test #22:
score: 0
Accepted
time: 12ms
memory: 10068kb
input:
1 50000 20 10001101111001100111 01011100001110100001 11010000110111110001 00010000101101100011 01111010110011100001 00100101101100000100 10101111100110110001 11100111001010101100 10011110110001111001 10111101010001111110 10100000000101110110 11000101100011110011 01000001010101101100 1000111000111100...
output:
0
result:
ok 1 number(s): "0"
Test #23:
score: 0
Accepted
time: 3ms
memory: 7664kb
input:
1 50000 20 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 00000000000000000000 0000000000000000...
output:
773579423
result:
ok 1 number(s): "773579423"
Test #24:
score: 0
Accepted
time: 5ms
memory: 6256kb
input:
1 20 50000 0000000000010000000000000000000000000000000000010100000000000000010000000000000000000000000000000000000000000100000000000000000000000000000000001000000000000000000000000000010000000000000000000000000000000000000001000000000000000010000000000000000000000000000000000000010000000000000000000...
output:
0
result:
ok 1 number(s): "0"
Test #25:
score: 0
Accepted
time: 6ms
memory: 6476kb
input:
1 20 50000 0000000100000000000000000000000000000000000000000000000000000000000000000001000001000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000100000000000000000000001000000010000000000000100000000000000000000000000000000000001000000000000000000000...
output:
0
result:
ok 1 number(s): "0"
Test #26:
score: 0
Accepted
time: 6ms
memory: 6320kb
input:
1 20 50000 0001100000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000001000000000000000000000000000000100000000000100100100000000000000000000000000010000000000...
output:
0
result:
ok 1 number(s): "0"
Test #27:
score: 0
Accepted
time: 17ms
memory: 22564kb
input:
1 500000 2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0...
output:
0
result:
ok 1 number(s): "0"
Test #28:
score: 0
Accepted
time: 24ms
memory: 24960kb
input:
1 500000 2 10 11 11 00 01 01 10 10 01 11 00 10 00 10 10 00 11 01 00 01 01 11 00 11 01 11 00 11 00 01 10 01 10 11 10 01 10 00 10 00 01 10 10 00 00 10 00 10 10 10 10 00 00 01 00 01 01 00 10 01 01 10 00 10 01 11 10 11 00 10 00 00 11 10 10 00 10 01 11 00 00 00 11 00 10 10 00 10 01 01 01 00 10 01 10 11 1...
output:
0
result:
ok 1 number(s): "0"
Test #29:
score: 0
Accepted
time: 17ms
memory: 22624kb
input:
1 500000 2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0...
output:
483815611
result:
ok 1 number(s): "483815611"
Test #30:
score: 0
Accepted
time: 19ms
memory: 25164kb
input:
1 2 500000 0110000100010010100001001000101011111100010010011111100000100001000000000010000001110000110110100110010011000010010000010100110011101100010100000000110111010001100000100010001110001110011001100001011010100000001001111100111110111010011000100010100100001001100000010000111010011110100000010...
output:
0
result:
ok 1 number(s): "0"
Test #31:
score: 0
Accepted
time: 22ms
memory: 27632kb
input:
1 2 500000 1000001111110110101010001010100100000100100010001100000101010011100001110010000101010011000101100110011111101001100000010000010000100110000100100011010100000000001001011010001100110011001001101001100111101100110111001110100100100000111001101100101111110001011101001110011110111111101011001...
output:
0
result:
ok 1 number(s): "0"
Test #32:
score: 0
Accepted
time: 23ms
memory: 26244kb
input:
1 2 500000 1000010001011001101010000000000000100010100000011010000011100110110101001000010110110101111101001100001110001111010100000111001011010000101010010110100111000000101100000100010000100001100011111000000111100111100010010111010001100100001011100101011111000011110011100011100110111100000010010...
output:
0
result:
ok 1 number(s): "0"
Test #33:
score: 0
Accepted
time: 39ms
memory: 42284kb
input:
1 1000000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
output:
235042059
result:
ok 1 number(s): "235042059"
Test #34:
score: 0
Accepted
time: 31ms
memory: 42256kb
input:
1 1000000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
output:
235042059
result:
ok 1 number(s): "235042059"
Test #35:
score: 0
Accepted
time: 24ms
memory: 50812kb
input:
1 1 1000000 111100111111100111011110110001111111111011111011011001111111101101101111101111110100101110111011111110101111111100111011110001111111101111011011111101110101111111111101101110011000111111110111101111111111111111101111110110101111101111111111111101111010111101011111101110111111010111000101...
output:
2
result:
ok 1 number(s): "2"
Test #36:
score: 0
Accepted
time: 34ms
memory: 47992kb
input:
1 1 1000000 110111111100110110011101111000101001110111111111101100110101111111000110111001111001111011111110101111110110111101111001111110110111010100111011001010110111111101010101111110111111111011010011010111111111100101111111011011111101011001110111111010110110100110010111111100111111111110110111...
output:
2
result:
ok 1 number(s): "2"
Test #37:
score: 0
Accepted
time: 50ms
memory: 3496kb
input:
100000 10 1 0 0 0 0 0 0 0 1 0 0 10 1 0 0 0 1 0 0 0 0 0 0 10 1 0 0 0 0 0 1 0 0 0 0 10 1 0 1 0 0 0 0 0 0 0 0 10 1 0 0 0 0 0 0 0 0 1 0 10 1 0 0 0 0 0 0 0 0 0 1 10 1 0 0 0 0 1 0 0 0 0 0 10 1 0 0 0 0 0 0 0 1 0 0 10 1 0 0 0 0 0 1 0 0 0 0 10 1 0 0 0 0 0 0 0 0 1 0 10 1 0 0 1 0 0 0 0 0 0 0 10 1 0 0 0 0 0 0 0...
output:
1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 1024 ...
result:
ok 100000 numbers
Extra Test:
score: 0
Extra Test Passed