//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-10;
const int MAXN = 1000010;
int n, a, b;
int main ()
{
RIII(n, a, b);
int p = 0;
while (n--)
{
int x;
RI(x);
if (p) printf(" "); p = 1;
cout << 1LL * x * a % b / a;
}
puts("");
return 0;
}
E. Mashmokh and Reverse Operation
将逆序数总结果按照区间大小分层,利用归并排序预处理每层逆序数之和,之后针对每层每次修改求和
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-10;
const int maxn = 1111111;
LL s[2][30];
int now[30];
LL pow2[30];
///0 1 n(wei0)
///n n-1 0
int A[maxn], T[maxn];
int n, m;
void merge_sort(int *A, int x, int y, int *T, int level)///求每层的严格逆序数
{
if (y <= x) return ;
int m = x + (y - x) / 2;
int p = x, q = m + 1, i = x;
merge_sort(A, x, m, T, level + 1);
merge_sort(A, m + 1, y, T, level + 1);
while (p <= m|| q <= y)
{
if (q > y || (p <= m && A[p] <= A[q])) T[i++] = A[p++];
else
{
s[0][level] += m - p + 1;
T[i++] = A[q++];
}
}
p = m, q = y, i = y;
while (p >= x && q > m)///求每层的严格顺序数
{
if (q <= m || (p >= x && A[p] >= A[q])) T[i--] = A[p--];
else
{
s[1][level] += p - x + 1;
T[i--] = A[q--];
}
}
for (int i = x; i <= y; i++) A[i] = T[i];
}
int main ()
{
pow2[0] = 1;
for (int i = 1; i <= 22; i++)
pow2[i] = pow2[i - 1] * 2;
RI(n);
REP(i, pow2[n]) RI(A[i]);
merge_sort(A, 0, pow2[n] - 1, T, 0);
RI(m);
while (m--)
{
int x; RI(x);
for (int i = x; i >= 1; i--)///子期间大小2^i
{
int y = n - i;///子区间个数2^y,同时也是递归的第y层
now[y] ^= 1;
}
LL ans = 0;
for (int i = 0; i <= n; i++) ans += s[now[i]][i];
cout << ans << endl;
}
return 0;
}
对于A数组的[l, m][m + 1, r]
调用方法是inplace_merge(A + l, A + m + 1, A + r + 1);一般效率是O(n),最差n*log(n)
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-10;
const int maxn = 1111111;
LL s[2][30];
int now[30];
LL pow2[30];
///0 1 n(wei0)
///n n-1 0
int A[maxn];
int n, m;
void merge_sort(int *A, int x, int y, int level)///求每层的严格逆序数
{
if (y <= x) return ;
int m = x + (y - x) / 2;
int p = x, q = m + 1, i = x;
merge_sort(A, x, m, level + 1);
merge_sort(A, m + 1, y, level + 1);
int s0 = x, s1 = x;
for (int i = m + 1; i <= y; i++)
{
for (; s0 <= m; s0++) if (A[s0] > A[i]) break;
for (; s1 <= m; s1++) if (A[s1] >= A[i]) break;
s[0][level] += m - s0 + 1;
s[1][level] += s1 - x;
}
inplace_merge(A + x, A + m + 1, A + y + 1);///就地排序两个已经排好的序列
}
int main ()
{
pow2[0] = 1;
for (int i = 1; i <= 22; i++)
pow2[i] = pow2[i - 1] * 2;
RI(n);
REP(i, pow2[n]) RI(A[i]);
merge_sort(A, 0, pow2[n] - 1, 0);
RI(m);
while (m--)
{
int x; RI(x);
for (int i = x; i >= 1; i--)///子期间大小2^i
{
int y = n - i;///子区间个数2^y,同时也是递归的第y层
now[y] ^= 1;
}
LL ans = 0;
for (int i = 0; i <= n; i++) ans += s[now[i]][i];
cout << ans << endl;
}
return 0;
}