#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;}
using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int N = 1e5 + 5;
const int M = 1e6 + 5;
const int Maxn = 1e9;
const int Minn = -1e9;
const int mod = 998244353;
int T_data, n, m, x;
int ans[M];
pair<int, int> d[N];
inline void add(int &x, int y)
{
x += y;
x >= mod ? x -= mod : 0;
}
inline void dec(int &x, int y)
{
x -= y;
x < 0 ? x += mod : 0;
}
int main()
{
read(n);
for (int i = 1, x; i <= n; ++i)
{
read(x);
d[i].first = 1;
while ((d[i].first << 1) <= x)
d[i].first <<= 1;
d[i].second = i;
}
std::sort(d + 1, d + n + 1);
m = d[n].first;
int r = 1;
for (int i = 1; i <= n; ++i)
{
while (ans[r])
++r;
for (int j = r; j <= m; j += d[i].first)
ans[j] = d[i].second;
}
for (int i = 1; i <= m; ++i)
if (!ans[i])
ans[i] = 1;
put(m), putchar('\n');
for (int i = 1; i <= m; ++i)
put(ans[i]), putchar(' ');
puts("");
return 0;
}
#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;}
using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int S = 1 << 16;
const int M = 105;
const int Maxn = 1e9;
const int Minn = -1e9;
const int mod = 998244353;
int pow2[M], a[20][20];
int m, T_data, n, ans;
int f[S], cnt[S]; bool vis[S];
inline void add(int &x, int y)
{
x += y;
x >= mod ? x -= mod : 0;
}
inline void dec(int &x, int y)
{
x -= y;
x < 0 ? x += mod : 0;
}
inline void mul2(int &x)
{
x += x;
x >= mod ? x -= mod : 0;
}
struct edge
{
int x, y, z;
edge() {}
edge(int X, int Y, int Z):
x(X), y(Y), z(Z) {}
inline bool operator < (const edge &a) const
{
if (z == a.z)
{
if (x == a.x)
return y < a.y;
else
return x < a.x;
}
else
return z < a.z;
}
}p[M];
int main()
{
read(n);
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
read(a[i][j]);
for (int i = 0; i < n; ++i)
for (int j = i + 1; j < n; ++j)
if (a[i][j])
p[++m] = edge(i, j, a[i][j]);
std::sort(p + 1, p + m + 1);
const int C = (1 << n) - 1;
pow2[0] = 1;
for (int i = 1; i <= m; ++i)
add(pow2[i] = pow2[i - 1], pow2[i - 1]);
for (int i = 0; i <= C; ++i)
cnt[i] = 1, vis[i] = true;
for (int i = 1; i <= m; ++i)
{
int x = p[i].x, y = p[i].y,
tx = 1 << x, ty = 1 << y,
w = tx | ty;
for (int s = 1; s <= C; ++s)
{
if (!vis[s])
continue ;
int &_f = f[s];
_f = cnt[s];
int low_s = s & -s, t = s ^ low_s;
if (!t)
continue ;
for (int s1 = (t - 1) & t; s1; s1 = (s1 - 1) & t)
{
int s2 = s1 ^ low_s;
if (f[s2])
dec(_f, 1ll * f[s2] * cnt[s ^ s2] % mod);
}
if (f[low_s])
dec(_f, 1ll * f[low_s] * cnt[t] % mod);
}
int num = pow2[i - 1];
int c = C ^ w;
for (int s = c; s; s = (s - 1) & c)
{
int s1 = s | w;
if (f[s1])
dec(num, 1ll * cnt[C ^ s1] * f[s1] % mod);
}
ans = (1ll * num * pow2[m - i] % mod * p[i].z + ans) % mod;
mul2(cnt[w]);
vis[w] = true;
for (int s = c; s; s = (s - 1) & c)
{
mul2(cnt[s | w]);
vis[s | w] = true;
vis[s] = vis[s | tx] = vis[s | ty] = false;
}
}
put(ans), putchar('\n');
return 0;
}
先将 n n n 个向量中共线的多余向量删除,记删除完多余向量后的向量个数为 n 0 n_0 n0,分别记为 v 1 → , v 2 → , … , v n 0 → \overrightarrow{v_1},\overrightarrow{v_2},\dots,\overrightarrow{v_{n_0}} v1,v2,…,vn0。
可以观察到, n 0 = 1 n_0 = 1 n0=1 时答案组成的图形是一条包含 d d d 个点的线段, n 0 = 2 n_0 = 2 n0=2 时答案组成的图形是一个包含 d 2 d^2 d2 个点的平行四边形。
对于任意的 n 0 n_0 n0,答案组成的图形即为包含 d n 0 d^{n_0} dn0 个点的 n 0 n_0 n0 维立方体在二维平面上的投影。
每次取出一个向量,将当前所有的点沿着该向量的方向平移 d − 1 d - 1 d−1 次,将得到的点加入当前点集,即可得到更高一维的立方体在二维平面上的投影。
现在唯一要解决的问题就是要保证每次新产生的点不能在原来的点对形成的直线上。
设这
n
0
n_0
n0 个每次平移的向量分别为
v
1
′
→
,
v
2
′
→
,
…
,
v
n
0
′
→
\overrightarrow{v_1'},\overrightarrow{v_2'},\dots,\overrightarrow{v_{n_0}'}
v1′,v2′,…,vn0′,其中
v
i
′
→
=
(
x
i
′
,
y
i
′
)
,
x
i
′
,
y
i
′
∈
Z
\overrightarrow{v_i'} = (x_i',y_i'),x_i',y_i'\in\mathbb Z
vi′=(xi′,yi′),xi′,yi′∈Z,考虑产生错误的情况,即
∃
a
1
,
a
2
,
…
,
a
n
0
,
∑
i
=
1
n
0
a
i
v
i
′
→
=
0
⇔
∑
i
=
1
n
0
a
i
x
i
′
=
0
,
∑
i
=
1
n
0
a
i
y
i
′
=
0
\exist a_1, a_2, \dots, a_{n_0}, \sum \limits_{i = 1}^{n_0}a_i\overrightarrow{v_i'} = 0 \Leftrightarrow \sum \limits_{i = 1}^{n_0}a_ix_i' =0, \sum \limits_{i = 1}^{n_0}a_iy_i' = 0
∃a1,a2,…,an0,i=1∑n0aivi′=0⇔i=1∑n0aixi′=0,i=1∑n0aiyi′=0
以 ∑ i = 1 n 0 a i x i ′ = 0 \sum \limits_{i = 1}^{n_0}a_ix_i' = 0 i=1∑n0aixi′=0 为例,取定 a n 0 a_{n_0} an0,其余 a i a_i ai 为未知量,该式可视为 n 0 − 1 n_0 - 1 n0−1 元不定方程,其无解的充分必要条件为 gcd ( x 1 ′ , x 2 ′ , … , x n 0 − 1 ′ ) ∤ ( a n 0 x n 0 ′ ) \gcd(x_1',x_2',\dots,x_{n_0 - 1}')\not| (a_{n_0}x_{n_0}') gcd(x1′,x2′,…,xn0−1′)∣(an0xn0′)。
取 n 0 n_0 n0 个大于 6 的互不相同的质数 m 1 , m 2 , … , m n 0 m_1, m_2, \dots, m_{n_0} m1,m2,…,mn0,令 M = ∏ i = 1 n 0 m i M = \prod\limits_{i = 1}^{n_0}m_i M=i=1∏n0mi, M i = M m i M_i =\frac{M}{m_i} Mi=miM,取 v i ′ → = M i v i → \overrightarrow{v_i'} = M_i \overrightarrow{v_i} vi′=Mivi,容易验证其满足条件。
#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;}
using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int N = 1e5 + 5;
const int Maxn = 1e9;
const int Minn = -1e9;
const int mod = 998244353;
int T_data, n, d;
inline void add(int &x, int y)
{
x += y;
x >= mod ? x -= mod : 0;
}
inline void dec(int &x, int y)
{
x -= y;
x < 0 ? x += mod : 0;
}
const int prime[] = {7, 11, 13, 19, 23, 29};
struct point
{
ll x, y;
point() {}
point(int X, int Y):
x(X), y(Y) {}
inline void scan()
{
read(x);
read(y);
ll z = std::__gcd(x, y);
x /= z;
y /= z;
}
inline point operator + (const point &a) const
{
return point(x + a.x, y + a.y);
}
inline point operator - (const point &a) const
{
return point(x - a.x, y - a.y);
}
inline point operator * (const ll &k)
{
return point(k * x, k * y);
}
inline ll operator * (const point &a) const
{
return x * a.y - y * a.x;
}
};
vector<point> a, ans, _ans;
int main()
{
read(n); read(d);
for (int i = 1; i <= n; ++i)
{
point u;
u.scan();
bool flag = true;
for (point v : a)
if (u * v == 0)
{
flag = false;
break ;
}
if (flag)
a.push_back(u);
}
ll prod = 1;
for (int i = 0, im = a.size(); i < im; ++i)
prod *= prime[i];
for (int i = 0, im = a.size(); i < im; ++i)
a[i] = a[i] * (prod / prime[i]);
ans.push_back(point(0, 0));
for (point u : a)
{
_ans.clear();
for (point v : ans)
for (int j = 1; j < d; ++j)
_ans.push_back(v + u * j);
for (point v : _ans)
ans.push_back(v);
}
put(ans.size()), putchar('\n');
for (point u : ans)
{
put(u.x), putchar(' ');
put(u.y), putchar('\n');
}
return 0;
}
a,第二种出现的字符串全部替换为 b,以此类推。要求将一个长度为
n
n
n 的字符串所有后缀的最小表示排序,按排名输出后缀起始位置。stable_sort 能大幅提高效率。#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;}
using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef unsigned int uint;
typedef long double ld;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int N = 2e5 + 255;
const int Maxn = 1e9;
const int Minn = -1e9;
const int mod = 998244353;
const int X = 131;
int T_data, n, _t, cur1[26], cur2[26];
int ans[N], Pow[N];
int lst[26][N], cnt[26][N];
int _sa[N][26], _rank[N][26];
char s[N];
int pos[26][N], h[26][N];
inline void add(int &x, int y)
{
x += y;
x >= mod ? x -= mod : 0;
}
inline void dec(int &x, int y)
{
x -= y;
x < 0 ? x += mod : 0;
}
int rank[N], height[N], sa[N], w[N], r, tn;
int f[22][N], Log[N], t[N];
inline bool Equal(int *x, int a, int b, int k)
{
if (x[a] != x[b])
return false;
else
{
int p = a + k > tn ? -1 : x[a + k],
q = b + k > tn ? -1 : x[b + k];
return p == q;
}
}
inline void initSA()
{
int *x = rank, *y = height;
r = tn + 200;
for (int i = 1; i <= tn; ++i)
++w[t[i]];
for (int i = 2; i <= tn; ++i)
w[i] += w[i - 1];
for (int i = tn; i >= 1; --i)
sa[w[t[i]]--] = i;
x[sa[1]] = r = 1;
for (int i = 2; i <= tn; ++i)
x[sa[i]] = t[sa[i - 1]] == t[sa[i]] ? r : ++r;
for (int k = 1; r < tn; k <<= 1)
{
int yn = 0;
for (int i = tn - k + 1; i <= tn; ++i)
y[++yn] = i;
for (int i = 1; i <= tn; ++i)
if (sa[i] > k)
y[++yn] = sa[i] - k;
for (int i = 1; i <= r; ++i)
w[i] = 0;
for (int i = 1; i <= tn; ++i)
++w[x[y[i]]];
for (int i = 2; i <= r; ++i)
w[i] += w[i - 1];
for (int i = tn; i >= 1; --i)
sa[w[x[y[i]]]--] = y[i];
std::swap(x, y);
x[sa[1]] = r = 1;
for (int i = 2; i <= tn; ++i)
x[sa[i]] = Equal(y, sa[i - 1], sa[i], k) ? r : ++r;
}
for (int i = 1; i <= tn; ++i)
rank[i] = x[i];
for (int i = 1, j, k = 0; i <= tn; ++i)
{
if (rank[i] == 1)
continue ;
k ? --k : 0;
j = sa[rank[i] - 1];
while (i + k <= tn && j + k <= tn && t[i + k] == t[j + k]) ++k;
height[rank[i]] = k;
}
height[1] = 0;
Log[0] = -1;
for (int i = 1; i <= tn; ++i)
Log[i] = Log[i >> 1] + 1, f[0][i] = height[i];
for (int j = 1, jm = Log[tn]; j <= jm; ++j)
for (int i = 1; i + (1 << j) - 1 <= tn; ++i)
f[j][i] = Min(f[j - 1][i], f[j - 1][i + (1 << j - 1)]);
}
inline int queryMin(int l, int r)
{
if (l > r)
std::swap(l, r);
++l;
int k = Log[r - l + 1];
return Min(f[k][l], f[k][r - (1 << k) + 1]);
}
inline bool cmp(const int &x, const int &y)
{
int res = Maxn;
for (int i = 0; i < 26; ++i)
{
int a = _sa[x][i],
b = _sa[y][i];
int px = lst[a][x],
py = lst[b][y];
if (px > n || py > n || px - x != py - y)
{
CkMin(res, Min(px - x + 1, py - y + 1));
continue ;
}
int lx = cnt[a][px],
ly = cnt[b][py];
int tmp = queryMin(rank[h[a][lx + 1]], rank[h[b][ly + 1]]);
if (pos[a][lx + tmp] <= n && pos[b][ly + tmp] <= n)
++tmp;
CkMin(res, Min(pos[a][lx + tmp] - x + 1,
pos[b][ly + tmp] - y + 1));
}
if (res > Min(n - x + 1, n - y + 1))
return x > y;
else
return _rank[x][s[x + res - 1]] < _rank[y][s[y + res - 1]];
}
inline bool cmp2(const int &x, const int &y)
{
return lst[x][_t] < lst[y][_t];
}
int main()
{
read(n);
scanf("%s", s + 1);
for (int i = 1; i <= n; ++i)
s[i] -= 'a';
for (int i = 1; i <= n; ++i)
{
for (int j = 0; j < 26; ++j)
cnt[j][i] = cnt[j][i - 1];
pos[s[i]][++cnt[s[i]][i]] = i;
}
for (int j = 0; j < 26; ++j)
{
lst[j][n + 1] = n + 1;
cnt[j][n + 1] = cnt[j][n] + 1;
pos[j][cnt[j][n + 1]] = n + 1;
}
for (int i = n; i >= 1; --i)
{
for (int j = 0; j < 26; ++j)
lst[j][i] = lst[j][i + 1];
lst[s[i]][i] = i;
for (int j = 0; j < 26; ++j)
_sa[i][j] = j;
_t = i;
std::sort(_sa[i], _sa[i] + 26, cmp2);
for (int j = 0; j < 26; ++j)
_rank[i][_sa[i][j]] = j;
}
for (int i = 0; i < 26; ++i)
{
for (int j = 1; j <= cnt[i][n + 1]; ++j)
{
t[++tn] = pos[i][j] - pos[i][j - 1];
h[i][j] = tn;
}
if (i < 25)
t[++tn] = n + i + 2;
}
initSA();
for (int i = 1; i <= n; ++i)
ans[i] = i;
std::stable_sort(ans + 1, ans + n + 1, cmp);
for (int i = 1; i <= n; ++i)
put(ans[i]), putchar(' ');
return 0;
}
#include
template <class T>
inline void read(T &res)
{
char ch; bool flag = false; res = 0;
while (ch = getchar(), !isdigit(ch) && ch != '-');
ch == '-' ? flag = true : res = ch ^ 48;
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - 48;
flag ? res = -res : 0;
}
template <class T>
inline void put(T x)
{
if (x > 9)
put(x / 10);
putchar(x % 10 + 48);
}
template <class T>
inline void _put(T x)
{
if (x < 0)
x = -x, putchar('-');
put(x);
}
template <class T>
inline void CkMin(T &x, T y) {x > y ? x = y : 0;}
template <class T>
inline void CkMax(T &x, T y) {x < y ? x = y : 0;}
template <class T>
inline T Min(T x, T y) {return x < y ? x : y;}
template <class T>
inline T Max(T x, T y) {return x > y ? x : y;}
template <class T>
inline T Abs(T x) {return x < 0 ? -x : x;}
template <class T>
inline T Sqr(T x) {return x * x;}
using std::map;
using std::set;
using std::pair;
using std::bitset;
using std::string;
using std::vector;
using std::multiset;
using std::priority_queue;
typedef long long ll;
typedef long double ld;
const ld pi = acos(-1.0);
const ld eps = 1e-8;
const int N = 1e5 + 5;
const int M = 2e6 + 5;
const int Maxn = 1e9;
const int Minn = -1e9;
const int mod = 998244353;
int S, T_data, n, q;
int a[N], sum[N], cnt[2][M];
ll fans[N], ans;
inline void add(int &x, int y)
{
x += y;
x >= mod ? x -= mod : 0;
}
inline void dec(int &x, int y)
{
x -= y;
x < 0 ? x += mod : 0;
}
struct query
{
int l, r, bl, id;
inline void scan(int t)
{
read(l); read(r);
++r; id = t;
bl = (l - 1) / S;
}
inline bool operator < (const query &a) const
{
return bl < a.bl || bl == a.bl && r < a.r;
}
}p[N];
inline void insertCol(int t, int c)
{
ans -= 1ll * cnt[t][c] * (cnt[t][c] - 1) / 2;
++cnt[t][c];
ans += 1ll * cnt[t][c] * (cnt[t][c] - 1) / 2;
}
inline void deleteCol(int t, int c)
{
ans -= 1ll * cnt[t][c] * (cnt[t][c] - 1) / 2;
--cnt[t][c];
ans += 1ll * cnt[t][c] * (cnt[t][c] - 1) / 2;
}
int main()
{
read(n); read(q);
S = sqrt(n + 1);
for (int i = 1; i <= n; ++i)
{
read(a[i]); --a[i];
sum[i + 1] = sum[i] ^ a[i];
}
for (int i = 1; i <= q; ++i)
p[i].scan(i);
std::sort(p + 1, p + q + 1);
int tl = 1, tr = 0;
for (int i = 1; i <= q; ++i)
{
int l = p[i].l, r = p[i].r;
while (tl < l)
{
deleteCol(tl & 1, sum[tl]);
++tl;
}
while (tl > l)
{
--tl;
insertCol(tl & 1, sum[tl]);
}
while (tr > r)
{
deleteCol(tr & 1, sum[tr]);
--tr;
}
while (tr < r)
{
++tr;
insertCol(tr & 1, sum[tr]);
}
fans[p[i].id] = 1ll * (r - l + 1) * (r - l) / 2 - ans;
}
for (int i = 1; i <= q; ++i)
put(fans[i]), putchar('\n');
return 0;
}