zoukankan      html  css  js  c++  java
  • [2013 ACM/ICPC Asia Regional Hangzhou Online J/1010]hdu 4747 Mex (线段树)

    题意:

    给定一个长度为 n 的非负数列,定义 mex(l, r) 为 l,r 区间里最小的没有出现的数字。

    求所有 mex(l, r) 的和

    分析参见 http://www.shuizilong.com/house/archives/hdu-4747-mex/

    我的代码:

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <vector>
      5 typedef long long ll;
      6 #define lson l, mid, rt << 1
      7 #define rson mid + 1, r, rt << 1 |1
      8 
      9 struct node {
     10     int mx, mi, setv;
     11     ll sum;
     12 };
     13 
     14 const int N = 200000 + 10;
     15 int ar[N];
     16 node seg[N << 2];
     17 
     18 bool vis[N];
     19 int idx;
     20 
     21 void Up(node& fa, node& ls, node& rs) {
     22     fa.mx = std::max(ls.mx , rs.mx);
     23     fa.sum = ls.sum + rs.sum;
     24     fa.mi = std::min(ls.mi, rs.mi);
     25 }
     26 void build(int l, int r, int rt) {
     27     seg[rt].setv = -1;
     28     if (l == r) {
     29         vis[ar[l]] = true;
     30         while (vis[idx])
     31             ++idx;
     32         seg[rt].mx = seg[rt].mi = seg[rt].sum = idx;
     33     } else {
     34         int mid = (l + r) >> 1;
     35         build(lson);
     36         build(rson);
     37         Up(seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
     38     }
     39 }
     40 void Down(node& fa, node& ls, node& rs, int len) {
     41     if (~fa.setv) {
     42         ls.setv = rs.setv = ls.mx = rs.mx = ls.mi = rs.mi = fa.setv;
     43         ls.sum = (ll)(len - (len >> 1)) * fa.setv;
     44         rs.sum = (ll)(len >> 1) * fa.setv;
     45         fa.setv = -1;
     46     }
     47 }
     48 ll query(int L, int R, int l, int r, int rt) {
     49     if (L == l && R == r)
     50         return seg[rt].sum;
     51     Down(seg[rt], seg[rt << 1], seg[rt << 1 | 1], r - l + 1);
     52     int mid = (l + r) >> 1;
     53     if (R <= mid) return query(L, R, lson);
     54     else if (L > mid) return query(L, R, rson);
     55     else return query(L, mid, lson) + query(mid + 1, R, rson);
     56 }
     57 void update(int L, int R, int v, int l, int r, int rt) {
     58     if (seg[rt].mx <= v) return ;
     59     int mid = (l + r) >> 1;
     60     if (L == l && R == r) {
     61         if (seg[rt].mi >= v) {
     62             seg[rt].mi = seg[rt].mx = seg[rt].setv = v;
     63             seg[rt].sum = (ll)(r - l + 1) * v;
     64             return ;
     65         }
     66         if (l == r) {
     67             if (seg[rt].mx > v) {
     68                 seg[rt].mi = seg[rt].mx = seg[rt].sum = v;
     69                 seg[rt].setv = -1;
     70             }
     71             return ;
     72         }
     73         //
     74         Down(seg[rt], seg[rt << 1], seg[rt << 1 | 1], r - l + 1);
     75         if (R <= mid) update(L, R, v, lson);
     76         else if (L > mid) update(L, R, v, rson);
     77         else {
     78             update(L, mid, v, lson);
     79             update(mid + 1, R, v, rson);
     80         }
     81         Up(seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
     82         //
     83     } else {
     84         Down(seg[rt], seg[rt << 1], seg[rt << 1 | 1], r - l + 1);
     85         if (R <= mid) update(L, R, v, lson);
     86         else if (L > mid) update(L, R, v, rson);
     87         else {
     88             update(L, mid, v, lson);
     89             update(mid + 1, R, v, rson);
     90         }
     91         Up(seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
     92     }
     93 }
     94 int n;
     95 
     96 int nex[N], hap[N];
     97 
     98 void work() {
     99     for (int i = 1; i <= n; ++i) {
    100         scanf("%d", &ar[i]);
    101         if (ar[i] > n)
    102             ar[i] = n + 1;
    103     }
    104     memset(vis, 0sizeof(vis));
    105     idx = 0;
    106     build(1, n, 1);
    107     ll ans = query(1, n, 1, n, 1);
    108 
    109     memset(hap, -1sizeof(hap));
    110     memset(nex, -1sizeof(nex));
    111 
    112     for (int i = 1; i <= n; ++i) {
    113         if (hap[ar[i]] == -1)
    114             hap[ar[i]] = i;
    115         else {
    116             nex[hap[ar[i]]] = i;
    117             hap[ar[i]] = i;
    118         }
    119     }
    120 
    121     int to;
    122     for (int i = 1; i <= n - 1; ++i) {
    123         if (nex[i] == -1)
    124             to = n;
    125         else
    126             to = nex[i] - 1;
    127         update(i, to, ar[i], 1, n, 1);
    128         ans = ans + query(i, n, 1, n, 1);
    129     }
    130     printf("%I64d ", ans);
    131 }
    132 int main() {
    133     while (1 == scanf("%d", &n)) {
    134         if (0 == n) break;
    135         work();
    136     }
    137     return 0;
    138 }
    View Code 


    CLJ有一个很诡异的map解法

     1 #include <vector>
     2 #include <string>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <set>
     7 #include <map>
     8 #include <sstream>
     9 #include <iomanip>
    10 #include <cstdio>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <cmath>
    14 using namespace std;
    15 typedef long long ll;
    16 typedef double du;
    17 #define pb push_back
    18 #define mp make_pair
    19 #define fi first
    20 #define se second
    21 #define FOR(i, s, t) for(i = (s); i < (t); i++)
    22 #define RFOR(i, s, t) for(i = (s)-1; i >= (t); i--)
    23 const int MAXN = 200004;
    24 
    25 int a[MAXN];
    26 int nextSame[MAXN], next[MAXN];
    27 bool vis[MAXN];
    28 map<intint> s;
    29 
    30 int main()
    31 {
    32     #ifdef __FIO
    33     freopen("in.txt""r", stdin);
    34     //freopen("out.txt", "w", stdout);
    35     #endif
    36     int T;
    37     //scanf("%d", &T);
    38     while(1){
    39         int n;
    40         int i, j, k;
    41         int si;
    42         ll sum, tsum;
    43         sum = tsum = 0;
    44         scanf("%d", &n);
    45         if(n == 0)
    46             break;
    47         for(i = 0; i < n; i++){
    48             scanf("%d", &a[i]);
    49             if(a[i] > n)
    50                 a[i] = n+1;
    51         }
    52         for(i = 0; i <= n+1; i++)
    53             next[i] = n;
    54         for(i = n-1; i >= 0; i--){
    55             nextSame[i] = next[a[i]];
    56             next[a[i]] = i;
    57         }
    58         memset(vis, 0sizeof vis);
    59         j = 0;
    60         s.clear();
    61         for(i = 0; i < n; i++){
    62             vis[a[i]] = true;
    63             while(vis[j])
    64                 j++;
    65             tsum += j;
    66             s[i] = j;
    67         }
    68         s[n] = n;
    69         sum += tsum;
    70         for(i = 0; i < n-1; i++){
    71             tsum -= s.begin()->se;
    72             s[i] = -1;
    73             map<intint>::iterator it = s.lower_bound(nextSame[i]-1);
    74             if(it->se > a[i]){
    75                 if(it->fi >= nextSame[i]){
    76                     int temp = it->se-a[i];
    77                     tsum -= (ll)temp*(nextSame[i]-1);
    78                     it--;
    79                     tsum += (ll)temp*it->fi;
    80                 }
    81                 while(it->se >= a[i]){
    82                     int temp = it->se-a[i];
    83                     tsum -= (ll)temp*it->fi;
    84                     s.erase(it--);
    85                     tsum += (ll)temp*it->fi;
    86                 }
    87                 s[nextSame[i]-1] = a[i];
    88             }
    89             s.erase(i);
    90             sum += tsum;
    91         }
    92         printf("%I64d ", sum);
    93     }
    94     return 0;
    95 }
    View Code 
  • 相关阅读:
    Spring 定时任务 @Scheduled cron表达式
    github 获取生成 token 的方法
    jQuery 获取当前日期及前一周或者后一周的日期
    jQuery 复选框 checkbox 取值和赋值
    git clone前后端项目之后的配置操作(一定不要忘记)
    springboo的postman后端接口测试流程详解
    Navicat Premium 15 永久破解激活工具及安装教程(亲测可用)
    企业微信的单点登录适配
    git的可视化和命令行操作步骤
    CMD中键入javac显示 javac不是内部或者外部命令
  • 原文地址:https://www.cnblogs.com/hewifi/p/3329168.html
Copyright © 2011-2022 走看看