zoukankan      html  css  js  c++  java
  • #1:来自辣鸡的初奏——6

    joyoi楼兰图腾,树状数组求逆序对的题,joyoi过不去,contesthunter过去了……

     1 #include <cstdio>
     2 #include <cstring>
     3 #define ll long long
     4 #define init(a, b) memset(a, b, sizeof(a))
     5 
     6 const int maxn = 200005;
     7 int n;
     8 int a[maxn], t[maxn];
     9 ll l[maxn], r[maxn];
    10 
    11 int ask(int x) {
    12     int ret = 0;
    13     for (; x; x -= x & (-x))    ret += t[x];
    14     return ret;
    15 }
    16 
    17 void add(int x, int cnt) {
    18     for (; x <= n; x += x & (-x))
    19         t[x] += cnt;
    20 }
    21 
    22 ll All() {
    23     ll ret = 0ll;
    24     for (int i = 0; i < n; i++)
    25         ret += l[i] * r[i];
    26     return ret;
    27 }
    28 
    29 ll solve0() {
    30     init(t, 0);
    31     init(l, 0);
    32     init(r, 0);
    33     for (int i = 0; i < n; i++) {
    34         l[i] += ask(n) - ask(a[i]);
    35         add(a[i], 1);
    36     }
    37     init(t, 0);
    38     for (int i = n-1; ~i; i--) {
    39         r[i] += ask(n) - ask(a[i]);
    40         add(a[i], 1);
    41     }
    42     return All();
    43 }
    44 
    45 ll solve1() {
    46     init(t, 0);
    47     init(l, 0);
    48     init(r, 0);
    49     for (int i = 0; i < n; i++) {
    50         l[i] += ask(a[i]-1);
    51         add(a[i], 1);
    52     }
    53     init(t, 0);
    54     for (int i = n-1; ~i; i--) {
    55         r[i] += ask(a[i]-1);
    56         add(a[i], 1);
    57     }
    58     return All();
    59 }
    60 
    61 int main() {
    62     scanf("%d", &n);
    63     for (int i = 0; i < n; i++) {
    64         scanf("%d", &a[i]);
    65     }
    66     printf("%lld %lld", solve0(), solve1());
    67 }
    View Code

    UVALive4329,枚举标杆是常见手段,其余的跟上一个题一样。然后发现上一个题写得过于直观可以优化。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 #define maxa 100001
     6 #define maxn 20005
     7 #define init(a, b) memset(a, b, sizeof(a))
     8 #define ll long long
     9 
    10 int n, T, maxx;
    11 int a[maxn], l[maxn], r[maxn];
    12 int t[maxa];
    13 
    14 int ask(int x) {
    15     int ret = 0;
    16     for (; x; x -= x & -x)  ret += t[x];
    17     return ret;
    18 }
    19 
    20 void add(int x, int cnt) {
    21     for (; x <= maxx; x += x & -x)  t[x] += cnt;
    22 }
    23 
    24 ll solve() {
    25     init(t, 0);
    26     init(l, 0);
    27     init(r, 0);  
    28     for (int i = 0; i < n; i++) {
    29         l[i] += ask(maxx) - ask(a[i]); 
    30         add(a[i], 1);
    31     }
    32     init(t, 0);
    33     for (int i = n-1; ~i; i--) {
    34         r[i] += ask(a[i] - 1);
    35         add(a[i], 1);
    36     }
    37 
    38     ll ret = 0ll;
    39     for (int i = 1; i < n-1; i++)
    40         ret += (ll)l[i] * r[i] + (ll)(i-l[i]) * (n-1-i-r[i]);
    41     return ret;
    42 }
    43 
    44 int main() {
    45     for (scanf("%d", &T); T; T--) {
    46         maxx = -1;
    47         scanf("%d", &n);
    48         for (int i = 0; i < n; i++) {
    49             scanf("%d", &a[i]);
    50             maxx = max(maxx, a[i]);
    51         }
    52         printf("%lld
    ", solve());
    53     }
    54     return 0;
    55 }
    View Code

    poj3468,画一画然后把和式改写一下会把问题降维,使前缀和数组的前缀和的和(orz)只与单个下标有关,就用树状数组维护了。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cctype>
     4 #include <algorithm>
     5 using namespace std;
     6 #define ri readint()
     7 #define gc getchar()
     8 #define ll long long
     9 #define maxn 100005
    10 
    11 int readint() {
    12     int x = 0, s = 1, c = gc;
    13     while (c <= 32)    c = gc;
    14     if (c == '-')    s = -1, c = gc;
    15     for (; isdigit(c); c = gc)    x = x * 10 + c - 48;
    16     return x * s;
    17 }
    18 
    19 int N, Q;
    20 ll sum[maxn], b[maxn][2];
    21 
    22 ll ask(int x, int flag) {
    23     ll ret = 0ll;
    24     for (; x; x -= x & -x)    ret += b[x][flag];
    25     return ret;
    26 }
    27 
    28 void add(int x, int cnt, int flag) {
    29     for (; x <= N; x += x & -x)    b[x][flag] += cnt;
    30 }
    31 
    32 int main() {
    33     N = ri, Q = ri;
    34     for (int i = 1; i <= N; i++) {
    35         int a = ri;
    36         sum[i] = sum[i-1] + a;
    37     }
    38     for (int i = 1; i <= Q; i++) {
    39         char ch;
    40         scanf("%c", &ch);
    41         int a = ri, y = ri;
    42         if (ch == 'Q') {
    43             printf("%lld
    ", sum[y] - sum[a-1] + (y+1)*ask(y, 0) - ask(y, 1) - a*ask(a-1, 0) + ask(a-1, 1));
    44         } else {
    45             int c = ri;
    46             add(a, c, 0);
    47             add(a, a*c, 1);
    48             add(y+1, -c, 0);
    49             add(y+1, (y+1)*(-c), 1);
    50         }
    51     }
    52     return 0;
    53 }
    View Code

    hihocoder1384,读题好吃力。倍增贪心选取。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #define ll long long
     6 #define maxn 500005
     7 using namespace std;
     8 
     9 int n, m, T, tmp;
    10 ll k, a[maxn], b[maxn], c[maxn];
    11 
    12 void merge(int l, int mid, int r) {
    13     for (int i = l, j = mid+1, k = l; k <= r; k++) {
    14         if (j > r || (i <= mid && b[i] <= b[j]))    c[k] = b[i++];
    15         else    c[k] = b[j++];
    16     }
    17 }
    18 
    19 ll cal(int l, int r) {
    20     if (r > n)    r = n;
    21     for (int i = tmp+1; i <= r; i++)    b[i] = a[i];
    22     sort(b+tmp+1, b+r+1);
    23     merge(l, tmp, r);
    24 
    25     int t = min(m, (r-l+1)/2);
    26     ll ret = 0ll;
    27     for (int i = 0; i < t; i++)
    28         ret += (c[r-i] - c[l+i]) * (c[r-i] - c[l+i]);
    29     return ret;
    30 }
    31 
    32 int solve() {
    33     int l = 1, r = 1, ans = 0;
    34     tmp = 1;
    35     b[1] = a[1];
    36     for (; l <= n; l = r+1, ans++) {
    37         int p = 1;
    38         while (p) {
    39             ll num = cal(l, r+p);
    40 
    41             if (num <= k) {
    42                 tmp = r = min(r+p, n);
    43                 for (int i = l; i <= r; i++)    b[i] = c[i];
    44                 p <<= 1;
    45             } else    p >>= 1;
    46 
    47             if (r == n)    break;
    48         }
    49     }
    50 
    51     return ans;
    52 }
    53 
    54 int main() {
    55     for (scanf("%d", &T); T; T--) {
    56         scanf("%d%d%lld", &n, &m, &k);
    57         for (int i = 1; i <= n; i++)
    58             scanf("%lld", &a[i]);
    59         printf("%d
    ", solve());
    60     }
    61     return 0;
    62 }
    View Code

    UVA11235,序列过于特殊,一大堆信息都能记录,然后可以套ST表。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int maxn = 1e5 + 5;
     7 const int maxnlog = 20;
     8 struct RMQ {
     9     int d[maxn][maxnlog];
    10 
    11     void init(int *A, int n) {
    12         for (int i = 1; i <= n; i++)    d[i][0] = A[i];
    13         for (int j = 1; (1<<j) <= n; j++)
    14             for (int i = 1; i+(1<<j)-1 <= n; i++)
    15                 d[i][j] = max(d[i][j-1], d[i+(1<<(j-1))][j-1]);
    16     }
    17 
    18     int query(int l, int r) {
    19         int k = 0;
    20         while ((1<<(k+1)) <= r - l + 1)    k++;
    21         return max(d[l][k], d[r-(1<<k)+1][k]);
    22     }
    23 }rmq;
    24 
    25 int n, q, a[maxn];
    26 int start, t;
    27 int cnt[maxn], num[maxn], left[maxn], right[maxn];
    28 
    29 int main() {
    30     while (~scanf("%d", &n) && n) {
    31         scanf("%d", &q);
    32         for (int i = 1; i <= n; i++)    scanf("%d", &a[i]);
    33         a[n+1] = a[n] + 1;
    34         t = 0;
    35         for (int i = 1; i <= n+1; i++) {
    36             if (i == 1 || a[i] > a[i-1]) {
    37                 if (i > 1) {
    38                     cnt[++t] = i - start;
    39                     for (int j = start; j < i; j++) {
    40                         num[j] = t;
    41                         left[j] = start;
    42                         right[j] = i - 1;
    43                     }
    44                 }
    45                 start = i;
    46             }
    47         }
    48 
    49         rmq.init(cnt, t);
    50         while (q--) {
    51             int a, b, ans;
    52             scanf("%d%d", &a, &b);
    53             if (num[a] == num[b])    ans = b - a + 1;
    54             else {
    55                 ans = max(right[a] - a + 1, b - left[b] + 1);
    56                 if (num[a]+1 < num[b])    ans = max(ans, rmq.query(num[a]+1, num[b]-1));
    57             }
    58             printf("%d
    ", ans);
    59         }
    60     }
    61     return 0;
    62 }
    View Code

    poj2182,本日做的最妙的题?树状数组是维护前缀和,但前缀和得自己琢磨好。然鹅最初的最初要把题目的内在本质探索明白才行。

     1 #include <cstdio>
     2 #include <cmath>
     3 #define maxn 8005
     4 
     5 int n, a[maxn];
     6 int c[maxn], h[maxn];
     7 
     8 void add(int x) {
     9     for (; x <= n; x += x&-x)    c[x]--;
    10 }
    11 
    12 int main() {
    13     scanf("%d", &n);
    14     for (int i = 1; i <= n; i++) {
    15         c[i]++;
    16         if (i + (i & -i) <= n)    c[i + (i & -i)] += c[i];
    17     }
    18     a[1] = 1;
    19     for (int i = 2; i <= n; i++) {
    20         scanf("%d", &a[i]);
    21         a[i]++;
    22     }
    23 
    24     int t = log(n) / log(2);
    25     for (int i = n; i; i--) {
    26         int ans = 0, sum = 0;
    27         for (int j = t; ~j; j--) {
    28             int p = 1<<j;
    29             if (ans + p <= n && sum + c[ans+p] < a[i]) {
    30                 ans += p;
    31                 sum += c[ans];
    32             }
    33         }
    34         add(h[i] = ans+1);
    35     }
    36 
    37     for (int i = 1; i <= n; i++)    printf("%d
    ", h[i]);
    38     return 0;
    39 }
    View Code
  • 相关阅读:
    【命令】set命令
    【命令】ln命令
    【命令】htop命令
    【命令】top命令
    【命令】ps命令
    【命令】kill命令
    【命令】pstree命令
    【进程/作业管理】篇章一:Linux进程及其管理(进程管理类工具)----pstree、ps、top、htop、kill、(killall、pkill、pgrep、pidof)
    【进程/作业管理】篇章四:Linux任务计划、周期性任务执行
    【进程/作业管理】篇章二:Linux系统作业控制(jobs)
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10336856.html
Copyright © 2011-2022 走看看