zoukankan      html  css  js  c++  java
  • Codeforces1198B Welfare State(分块)

    题目链接:http://codeforces.com/problemset/problem/1198/B

    题目大意:n个数据,q个操作,每个操作有两种情况,一种是将某一个数据改为x,另一种是将所有小于x的数据改为x。所有操作结束后输出数组。

    这道题是我第一次在非练习(就是那种半天一题磨洋工状态)情况下用分块解决了题目,所以写篇详解纪念一下。

    这道题大佬们的写法貌似不是分块emmmm,也对,根据题目输出的特殊性或许有别的办法,但蒟蒻我目前能想到的只有分块了。(莽过了就好)

    思路就是用一个mi数组记录每个块的最小值,一个mark数组记录该块是否被修改过(详细解释见下)。

    显然的,对于第二种操作,如果某个块的最小值大于x,那我们就不用对这个块进行操作。反之,我们把这个块的最小值标为x,并且让这个块的mark置1。然后,对于mark置1的块,如果我们的操作1访问到它了,就遍历一次块,将每个<=x的数改为x,再进行修改。

    输出的时候只要注意判断一下mark的状态就行了。最坏的情况两种修改的复杂度都是O根号n。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<set>
     4 #include<stdio.h>
     5 #include<string.h>
     6 #include<math.h>
     7 #include<vector>
     8 #include<stdlib.h>
     9 #include<queue>
    10 #include<algorithm>
    11 #include<map>
    12 #include<stack>
    13 using namespace std;
    14 int a[200005];
    15 int bl[200005];
    16 int blo;
    17 int mi[2005];//每个块的最小值
    18 int mark[2005];//标记状态
    19 int le[2005];//每个块的左边界
    20 int ri[2005];//每个块的右边界
    21 int main()
    22 {
    23     int n;
    24     scanf("%d",&n);
    25     blo=sqrt(n);
    26     memset(mi,-1,sizeof(mi));
    27     for(int i=1;i<=n;i++)
    28     {
    29         scanf("%d",&a[i]);
    30         bl[i]=(i-1)/blo+1;
    31         if(mi[bl[i]]==-1||a[i]<mi[bl[i]])
    32         {
    33             mi[bl[i]]=a[i];
    34         }
    35         if(le[bl[i]]==0)
    36         {
    37             le[bl[i]]=i;
    38         }
    39         ri[bl[i]]=i;
    40     }
    41     int q;
    42     memset(mark,-1,sizeof(mark));
    43     scanf("%d",&q);
    44     int k,p,x;
    45     while(q--)
    46     {
    47         scanf("%d",&k);
    48         if(k==1)
    49         {
    50             scanf("%d%d",&p,&x);
    51             if(mark[bl[p]]==1)
    52             {
    53                 for(int i=le[bl[p]];i<=ri[bl[p]];i++)
    54                 {
    55                     if(a[i]<mi[bl[p]])
    56                     {
    57                         a[i]=mi[bl[p]];
    58                     }
    59                 }
    60                 mark[bl[p]]=-1;
    61             }
    62             a[p]=x;
    63             if(x<mi[bl[p]])
    64             {
    65                 mi[bl[p]]=x;
    66             }
    67         }
    68         else
    69         {
    70             scanf("%d",&x);
    71             for(int i=1;i<=bl[n];i++)
    72             {
    73                 if(mi[i]>=x)
    74                 {
    75                     continue;
    76                 }
    77                 else
    78                 {
    79                     mi[i]=x;
    80                     mark[i]=1;
    81                 }
    82             }
    83         }
    84     }
    85     for(int i=1;i<=n;i++)
    86     {
    87         if(mark[bl[i]]==-1||a[i]>=mi[bl[i]])
    88         {
    89             printf("%d%c",a[i],i==n?'
    ':' ');
    90         }
    91         else
    92         {
    93             printf("%d%c",mi[bl[i]],i==n?'
    ':' ');
    94         }
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    新手讲排序:希尔排序
    安装部署VMware vSphere 5.5文档 (6-6) 集群和vMotion
    安装部署VMware vSphere 5.5文档 (6-5) 安装配置vCenter
    同步VDP时间
    vdp配置
    python定义常量
    OpenStack Keystone V3 简介
    nginx + uswgi +django
    安装系统
    Standard NSD file
  • 原文地址:https://www.cnblogs.com/forever3329/p/11274607.html
Copyright © 2011-2022 走看看