cf 240 div2

来源:互联网 发布:php框架怎么用 编辑:程序博客网 时间:2024/05/01 13:37

B. Mashmokh and Tokens

//#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   0int 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;}


inplace_merge()是对两个已排好序的序列,就地排序

对于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   0int 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;}


0 0
原创粉丝点击