• HDU


    HDU-4747

    题意:对于每一段连续区间找到mex的值(mex 即为没出现过的数的最小非负数),然后对所有的改值进行求和, 输出ans。

    题解:首先我门可以暴力的跑出 区间 [1,2], [1,3],……,[1,i]的mex值, 由于mex的定义, 我们可以得知, 左边的区间mex一定是不大于右边的区间的mex值, 然后可以通过线段树求和, 来访问这些值的和。 然后查询完一次数据之后, 我们将删除第一个数, 并且判断在[l+1,r-1](l为被删数出现的位置, r为下一个该数出现的位置) 的区间内是否有mex值大于该删除的值, 如果有就更新这一段区间的值, 用线段树加速更新操作,最后删完所有的点所统计的和就是答案了。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define max3(a,b,c) max(a,max(b,c))
     12 #define min3(a,b,c) min(a,min(b,c))
     13 typedef pair<int,int> pll;
     14 const int INF = 0x3f3f3f3f;
     15 const LL mod = 1e9+7;
     16 const int N = 2e5+10;
     17 LL Max[N<<2], sum[N<<2], lazy[N<<2];
     18 int a[N], mex[N];
     19 void PushUp(int rt){
     20     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     21     Max[rt] = max(Max[rt<<1|1], Max[rt<<1]);
     22 }
     23 void PushDown(int rt, int llen, int rlen){
     24     if(lazy[rt] != -1){
     25         lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
     26         sum[rt<<1] = lazy[rt]*llen;
     27         sum[rt<<1|1] = lazy[rt]*rlen;
     28         Max[rt<<1] = Max[rt<<1|1] = lazy[rt];
     29         lazy[rt] = -1;
     30     }
     31 }
     32 void Build(int l, int r, int rt){
     33     lazy[rt] = -1;
     34     if(l == r) {
     35         Max[rt] = sum[rt] = mex[l];
     36         return ;
     37     }
     38     int m = l+r >> 1;
     39     Build(lson);
     40     Build(rson);
     41     PushUp(rt);
     42 }
     43 void Update(int l, int r, int rt, int L, int R, int c){
     44     if(L <= l && r <= R){
     45         Max[rt] = lazy[rt] = c;
     46         sum[rt] = 1ll * (r-l+1) * c;
     47         return ;
     48     }
     49     int m = l+r >> 1;
     50     PushDown(rt, m-l+1, r-m);
     51     if(L <= m) Update(lson, L, R, c);
     52     if(m < R) Update(rson, L, R, c);
     53     PushUp(rt);
     54 }
     55 LL Query(int l, int r, int rt, int L, int R){
     56     if(L <= l && r <= R)  return sum[rt];
     57     int m = l+r >> 1;
     58     LL ret = 0;
     59     PushDown(rt, m-l+1, r-m);
     60     if(L <= m) ret += Query(lson, L, R);
     61     if(m < R)  ret += Query(rson, L, R);
     62     return ret;
     63 }
     64 int id(int l, int r, int rt, int v){
     65     if(l == r) return l;
     66     int m = l+r >> 1;
     67     PushDown(rt, m-l+1, r-m);
     68     if(Max[rt<<1] > v) return id(lson, v);
     69     return id(rson, v);
     70 }
     71 map<int, int> mp;
     72 int Next[N];
     73 int main(){
     74     ///Fopen;
     75     int n;
     76     while(~scanf("%d", &n), n){
     77         for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
     78         mp.clear();
     79         int tmp = 0;
     80         for(int i = 1; i <= n; i++){
     81             mp[a[i]] = 1;
     82             while(mp.count(tmp)) tmp++;
     83             mex[i] = tmp;
     84         }
     85 
     86         mp.clear();
     87         for(int i = n; i >= 1; i--){
     88             if(!mp.count(a[i])) Next[i] = n + 1;
     89             else Next[i] = mp[a[i]];
     90             mp[a[i]] = i;
     91         }
     92         Build(1,n,1);
     93         LL ans = 0;
     94         for(int i = 1; i <= n; i++){
     95             ans += sum[1];
     96             if(Max[1] > a[i]){
     97                 int l = id(1,n,1,a[i]);//找到最左边的大于被删除数的位置,由mex的定义可知,后面的值一定也不小于这个节点
     98                 int r = Next[i];
     99                 if(l < r) Update(1, n, 1, l, r-1, a[i]);
    100             }
    101             Update(1,n,1,i,i,0);
    102         }
    103         printf("%I64d
    ", ans);
    104     }
    105     return 0;
    106 }
    HDU 4747
  • 相关阅读:
    RedHat5.8 编译内核驱动 合成initrd.img
    matrix-gui-2.0 将javascript文件夹改成js文件夹
    使用PHP配置文件
    Ubuntu 16.10 Apache PHP Server
    Ubuntu 16.10 中文环境 Shell输出英文提示
    制作SD卡img文件,并扩容
    Linux syslogd
    Windows cmd findstr
    jquery ztree异步搜索
    怎样在点击li时添加样式,移除兄弟样式
  • 原文地址:https://www.cnblogs.com/MingSD/p/9098220.html
Copyright © 2020-2023  润新知