Section 4.1 4.2

master
大蒟蒻 9 years ago
parent e46b28299e
commit aef1c50fe4

@ -0,0 +1,49 @@
#include <cstdio>
#include <cctype>
inline int min(int a, int b) { return a < b ? a : b; }
inline int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); }
inline void read(int &x)
{
int ch = x = 0;
while (!isdigit(ch = getchar()));
for (; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + ch - '0';
}
int n, a[1 << 20 | 1], Log[1 << 20 | 1];
int M[1 << 20 | 1][20], G[1 << 20 | 1][20];
struct
{
int c, a[1 << 20 | 1], r;
}ans;
inline bool can(int l, int r)
{
int k = Log[r - l + 1];
return min(M[l][k], M[r - (1 << k) + 1][k]) == gcd(G[l][k], G[r - (1 << k) + 1][k]);
}
bool check(int len)
{
int cnt = 0;
for (int i = 0; i + len < n; i++)
if (can(i, i + len))
ans.a[cnt++] = i;
if (cnt) ans.r = len, ans.c = cnt;
return cnt;
}
int main()
{
read(n);
Log[0] = -1;
for (int i = 1; i <= n; i++) Log[i] = Log[i >> 1] + 1;
for (int i = 0; i < n; i++) read(a[i]);
for (int i = 0; i < n; i++) M[i][0] = G[i][0] = a[i];
for (int j = 1; j <= Log[n]; j++)
for (int i = 0; i + (1 << j) - 1 < n; i++)
M[i][j] = min(M[i][j - 1], M[i + (1 << (j - 1))][j - 1]),
G[i][j] = gcd(G[i][j - 1], G[i + (1 << (j - 1))][j - 1]);
int L = 0, R = n, m;
while (L < R)
check(m = (L + R) >> 1) ? L = m + 1 : R = m;
printf("%d %d\n", ans.c, ans.r);
for (int i = 0; i < ans.c; i++)
printf("%d ", ans.a[i] + 1);
return 0;
}

@ -0,0 +1,13 @@
void add(int x, int v)
{
for (; x <= n; x += lowbit(x))
A[x] += v;
}
void sum(int x)
{
int res = 0;
for (; x; x -= lowbit(x))
res += A[x];
return res;
}

@ -0,0 +1,42 @@
#include <algorithm>
#include <cstdio>
#define lowbit(x) ((x) & -(x))
const int N = 20005;
void add(int *arr, int pos, int val)
{
for (; pos < N; pos += lowbit(pos))
arr[pos] += val;
}
int query(int *arr, int pos)
{
int ans = 0;
for (; pos; pos -= lowbit(pos))
ans += arr[pos];
return ans;
}
int sum[2][N];
struct cow
{
int pos, vol;
bool operator<(const cow &rhs) const { return vol < rhs.vol; }
} cows[N];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &cows[i].vol, &cows[i].pos);
std::sort(cows + 1, cows + n + 1);
long long ans = 0;
for (int i = 1; i <= n; i++)
{
long long a = query(sum[0], cows[i].pos), b = query(sum[1], cows[i].pos);
ans += (cows[i].pos * a - b + query(sum[1], 20000) - b -
(i - 1 - a) * cows[i].pos) *
cows[i].vol;
add(sum[0], cows[i].pos, 1);
add(sum[1], cows[i].pos, cows[i].pos);
}
printf("%lld", ans);
return 0;
}

@ -0,0 +1,42 @@
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <stdint.h>
#define lowbit(x) ((x) & -(x))
const int N = 500005;
int sum[N];
int query(int x)
{
int ans = 0;
for (; x; x -= lowbit(x)) ans += sum[x];
return ans;
}
void update(int x, int y)
{
for (; x <= N; x += lowbit(x)) sum[x] += y;
}
struct abcd
{
int val, pos;
bool operator<(const abcd &rhs) const { return val < rhs.val; }
} nodes[N];
int map[N];
int main()
{
int n;
while (~scanf("%d", &n) && n)
{
memset(sum, 0, sizeof(sum));
for (int i = 1; i <= n; i++) scanf("%d", &nodes[i].val), nodes[i].pos = i;
std::sort(nodes + 1, nodes + n + 1);
for (int i = 1; i <= n; i++) map[nodes[i].pos] = i;
int64_t ans = 0;
for (int i = 1; i <= n; i++)
{
update(map[i], 1);
ans += i - query(map[i]);
}
printf("%lld\n", ans);
}
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

@ -0,0 +1,30 @@
#include <cstdio>
#include <cstring>
#define lowbit(x) ((x) & -(x))
const int maxn = 1 << 15 | 1;
int a[maxn], n, m, level[maxn];
void update(int pos, int x)
{
for (; pos < maxn; pos += lowbit(pos)) a[pos] += x;
}
int query(int pos)
{
int ans = 0;
for (; pos; pos -= lowbit(pos)) ans += a[pos];
return ans;
}
int main()
{
scanf("%d", &n);
memset(level, 0, sizeof(level));
memset(a, 0, sizeof(a));
for (int i = 0, x, y; i < n; ++i)
{
scanf("%d%d", &x, &y);
level[query(++x)]++;
update(x, 1);
}
for (int i = 0; i < n; ++i)
printf("%d\n", level[i]);
return 0;
}

@ -0,0 +1,29 @@
#include <cstdio>
inline int min(int a, int b) { return a < b ? a : b; }
inline int max(int a, int b) { return a > b ? a : b; }
const int N = 50010;
const int LogN = 16;
int minT[LogN][N], maxT[LogN][N], Log[N];
int main()
{
Log[0] = -1;
for (int i = 1; i < N; i++) Log[i] = Log[i >> 1] + 1;
int m, n;
scanf("%d%d", &n, &m);
for (int i = 1, x; i <= n; i++)
{
scanf("%d", &x);
minT[0][i] = maxT[0][i] = x;
}
for (int j = 1; j < LogN; j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++)
minT[j][i] = min(minT[j - 1][i], minT[j - 1][i + (1 << (j - 1))]),
maxT[j][i] = max(maxT[j - 1][i], maxT[j - 1][i + (1 << (j - 1))]);
for (int i = 1, x, y, z; i <= m; i++)
{
scanf("%d%d", &x, &y);
z = Log[y - x + 1];
printf("%d\n", max(maxT[z][x], maxT[z][y - (1 << z) + 1]) - min(minT[z][x], minT[z][y - (1 << z) + 1]));
}
return 0;
}

@ -284,15 +284,13 @@ Manacher 模板题
\paragraph{中国剩余定理}
$m_1,m_2,m_3,\ldots,m_r$是两两互素的正整数,则同余方程组
\begin{equation}
\left\{
\begin{aligned}
\left\{\begin{aligned}
& x\equiv a_1\pmod{m_1}\\
& x\equiv a_2\pmod{m_2}\\
& x\equiv a_3\pmod{m_3}\\
& \cdots\\
& x\equiv a_r\pmod{m_r}\\
\end{aligned}
\right.
\end{aligned}\right.
\end{equation}
$\mod M=\prod\limits_1^r m$的唯一解,即为中国剩余定理。\\
$n=pq$$gcd(p,q)=1$,那么$x\mod p,x\mod q$的值确定后,$x\mod n$的值也会随之确定。
@ -330,10 +328,40 @@ Manacher 模板题
$$gcd(a,n)=1\Rightarrow Ord_n(a)|\varphi(n)$$
$$\mbox{特别的,}p\in\mathbb{P},gcd(a,p)=1\Rightarrow Ord_p(a)|p-1\mbox{,显然}\varphi(p)=p-1$$
\paragraph{原根} $n\in\mathbb{N_+},a\in\mathbb{Z},Ord_n(a)=\varphi(n)$,则称$a$为模$n$的一个原根,由阶的定义可知原根和$n$必然互质。
\paragraph{求质数$p$的原根算法}
暴力从小到大枚举$g\in\mathbb{N_+}$$\forall a\in\{x\;|\;x|p-1,x\in\mathbb{P}\},g^{\frac{p-1}{a}}\not\equiv1\pmod{p}$
\paragraph{求质数$p$的原根算法} 暴力从小到大枚举$g\in\mathbb{N_+}$$\forall a\in\{x\;|\;x|p-1,x\in\mathbb{P}\},g^{\frac{p-1}{a}}\not\equiv1\pmod{p}$
\codeinput[Primitive Root]{assets/day3/proot.cpp}
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=1284}{POJ1284} - Primitive Roots} 如果$n\in\mathbb{N_+}$有一个原根,那么$n$一共有$\varphi(\varphi(n))$个不同余的原根
\codeinput[Primitive Roots]{assets/day3/poj1284.cpp}
\section{day4 数据结构}
\subsection{树状数组}$\lg{n}$的时间内更新或查询$\sum\limits_{i=1}^n a_i$
\paragraph{lowbit} \verb|lowbit(x) = x & -x|
\paragraph{两个操作} $\lg{n}$更新或查询
\codeinput[Fenwick tree]{assets/day4/FenwickTree.cpp}
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=2352}{POJ2352} - Stars} 。。。
\codeinput[Stars]{assets/day4/poj2352.cpp}
\subparagraph{\href{http://poj.org/problem?id=2299}{POJ2299} - Ultra-QuickSort} 求逆序对数量,不过配图是啥玩意?马桶橛子?
\codeinput[Ultra-QuickSort]{assets/day4/poj2299.cpp}
\begin{center}\includegraphics[height=10cm]{assets/day4/poj2299.jpg}\end{center}
\subparagraph{\href{http://poj.org/problem?id=1990}{POJ1990} - MooFest} 杀光奶牛问题就会得到解决
\codeinput[MooFest]{assets/day4/poj1990.cpp}
\subsection{Sparse Table} 处理区间最值,即 RMQRange Minimum Query问题。
\paragraph{预处理} 计算一个数组$f$,使$f[i][j]=min[i,i+2^j)$,然后你就可以开始倍增了。
\begin{eqnarray}
f[i][j]=\left\{\begin{array}{lr}
a[i] & j=0 \\
min(f[i][j-1],f[i+2^{j-1}][j-1]) & j>0
\end{array}\right.
\end{eqnarray}
\paragraph{询问}
考虑一个询问区间$[x,y)$的最小值的询问操作。\\
我们可以求出满足$2^i\le y-x < 2^{i+1}$$i$,即$\lfloor\log_2{y-x}\rfloor$,这样我们可以用两个长度为$2^i$的小区间覆盖询问的大区间。\\
而长度为$2^i$的小区间的最小值在预处理时已经求出,于是区间$[x,y)$的最小值为$min\{f[x][i],f[y-2^i][i]\}$,由于是求最值,区间有交集也没关系。
\paragraph{练习题}
\subparagraph{\href{http://poj.org/problem?id=3264}{POJ3264} - Balanced Lineup}
给你一个长度为$n$的序列$a[N]$,询问$Q$次,每次输出$[L,R]$区间最大值与最小值的差是多少,果真这种简化了的题面真是清晰易懂。
\codeinput[Balanced Lineup]{assets/day4/poj3264.cpp}
\subparagraph{\href{http://codeforces.com/problemset/problem/359/D}{CF359D} - Pair of Numbers} 首先要知道gcd有“最值的性质”然后二分暴力。
\codeinput[Pair of Numbers]{assets/day4/CF359D.cpp}
\end{document}
Loading…
Cancel
Save