• Codeforces Round #576 (Div. 2) D


    Codeforces Round #576 (Div. 2)

    D - Welfare State

    There is a country with n citizens. The i-th of them initially has ai money. The government strictly controls the wealth of its citizens. Whenever a citizen makes a purchase or earns some money, they must send a receipt to the social services mentioning the amount of money they currently have.

    Sometimes the government makes payouts to the poor: all citizens who have strictly less money than x are paid accordingly so that after the payout they have exactly x money. In this case the citizens don't send a receipt.

    You know the initial wealth of every citizen and the log of all events: receipts and payouts. Restore the amount of money each citizen has after all events.

    Input

    The first line contains a single integer n (1≤n≤2⋅10^5) — the numer of citizens.

    The next line contains n integers a1, a2, ..., an (0≤ai≤10^9) — the initial balances of citizens.

    The next line contains a single integer q (1≤q≤2⋅10^5) — the number of events.

    Each of the next q lines contains a single event. The events are given in chronological order.

    Each event is described as either 1 p x (1≤p≤n, 0≤x≤10^9), or 2 x (0≤x≤10^9). In the first case we have a receipt that the balance of the p-th person becomes equal to x. In the second case we have a payoff with parameter x.

    Output

    Print n integers — the balances of all citizens after all events.

    Examples

    input

    4

    1 2 3 4

    3

    2 3

    1 2 2

    2 1

    output

    3 2 3 4

    input

    5

    3 50 2 1 10

    3

    1 2 0

    2 8

    1 3 20

    output

    8 8 20 8 10

    Note

    In the first example the balances change as follows: 1 2 3 4 → 3 3 3 4 → 3 2 3 4 → 3 2 3 4

    In the second example the balances change as follows: 3 50 2 1 10 → 3 0 2 1 10 → 8 8 8 8 10 → 8 8 20 8 10

     

    题意:题目意思就是给你n个数,m次操作,有两种不同的操作,

    操作一就是单点修改,把指定位置的数改成所给的数。

    操作二就是给你一个数,对于所有n个数,如果小于所给数就变成这个数。

    最后要求输出操作后的整个数组。

    思路:常规写法,可以用线段树维护一个最大值解决,单点修改+区间修改。

    另外有一个神仙写法就是先把所有操作存起来,在从后往前预处理扫一遍操作,

    我们可以根据操作2的查询计算最大值x,并记住每个公民的最后一个类型1的查询,

    最后输出答案。

    线段树写法:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<map>
      7 #include<set>
      8 #include<vector>
      9 #include<queue>
     10 #include<list>
     11 #include<stack>
     12 #include<unordered_map>
     13 using namespace std;
     14 #define ll long long 
     15 const int mod=1e9+7;
     16 const int inf=1e9+100;
     17  
     18 const int maxn=1e6+10;
     19  
     20 typedef struct tree
     21 {
     22     int left;
     23     int right;
     24     int maxx;
     25     int lan_mark;
     26 } St;
     27  
     28 St tree[maxn<<2];
     29  
     30 int n,m;
     31  
     32 inline void up(int k)
     33 {
     34     tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx);
     35 }
     36  
     37 inline void build_tree(int k,int left,int right)
     38 {
     39     tree[k].left=left;
     40     tree[k].right=right;
     41     tree[k].lan_mark=0;
     42     if(left==right)
     43     {
     44         scanf("%d",&tree[k].maxx);
     45         
     46         return; 
     47     }
     48     
     49     int mid=(left+right)>>1;
     50     
     51     build_tree(k*2,left,mid);
     52     build_tree(k<<1|1,mid+1,right);
     53     
     54     up(k);
     55 }
     56  
     57 inline void down(int k)
     58 {
     59     int now=tree[k].lan_mark;
     60     
     61     tree[k<<1].maxx=max(tree[k<<1].maxx,now);
     62     tree[k<<1|1].maxx=max(tree[k<<1|1].maxx,now);
     63     
     64     tree[k<<1].lan_mark=max(tree[k<<1].lan_mark,now);
     65     tree[k<<1|1].lan_mark=max(tree[k<<1|1].lan_mark,now);
     66     
     67     tree[k].lan_mark=0;
     68 }
     69  
     70 inline void update1(int k,int left,int right,int x)
     71 {
     72     if(tree[k].left>=left&&tree[k].right<=right)
     73     {
     74         tree[k].maxx=x;
     75         return ;
     76     }
     77     
     78     if(tree[k].lan_mark)
     79         down(k);
     80     
     81     int mid=(tree[k].left+tree[k].right)>>1;
     82     
     83     if(mid>=left)
     84         update1(k<<1,left,right,x);
     85     
     86     if(mid<right) 
     87         update1(k<<1|1,left,right,x);
     88     
     89     up(k);
     90 }
     91  
     92 inline void update2(int k,int x)
     93 {
     94     tree[k].maxx=max(tree[k].maxx,x);
     95     tree[k].lan_mark=max(tree[k].lan_mark,x);
     96     return ;
     97 }
     98  
     99 inline int query(int k,int left,int right)
    100 {
    101     if(tree[k].left==left&&tree[k].right==right)
    102     {
    103         return tree[k].maxx;
    104     }
    105     
    106     int mid=(tree[k].left+tree[k].right)>>1;
    107     
    108     if(tree[k].lan_mark)
    109         down(k);
    110     
    111     if(mid>=left)
    112         return query(k<<1,left,right);
    113     
    114     if(mid<right)
    115         return query(k<<1|1,left,right);
    116     
    117 }
    118  
    119 int main()
    120 {
    121 //    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    122  
    123     scanf("%d",&n);
    124     
    125     build_tree(1,1,n);
    126     
    127     scanf("%d",&m);
    128     int op;
    129     int place,x;
    130     for(int i=0;i<m;i++)
    131     {
    132         scanf("%d",&op);
    133         
    134         if(op==1)
    135         {
    136             scanf("%d%d",&place,&x);
    137             
    138             update1(1,place,place,x);
    139         }
    140         else if(op==2)
    141         {
    142             scanf("%d",&x);
    143             
    144             update2(1,x);
    145         }
    146     }
    147     
    148     for(int i=1;i<=n;i++)
    149     {
    150         printf("%d",query(1,i,i));
    151         
    152         if(i==n)
    153             printf("
    ");
    154         else
    155             printf(" ");
    156     }
    157     
    158     return 0;
    159 }

     神仙写法:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<map>
     7 #include<set>
     8 #include<vector>
     9 #include<queue>
    10 #include<list>
    11 #include<stack>
    12 #include<unordered_map>
    13 using namespace std;
    14 #define ll long long 
    15 const int mod=1e9+7;
    16 const int inf=1e9+100;
    17  
    18 const int maxn=2e5+10;
    19  
    20 pair<int,int> v[maxn];
    21  
    22 int quary[maxn];
    23  
    24 int pre[maxn];
    25  
    26 int main()
    27 {
    28     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    29     
    30     int n,m,op;
    31     int place,x;
    32     while(cin>>n)
    33     {
    34         for(int i=0;i<n;i++)
    35         {
    36             cin>>v[i].first;
    37             v[i].second=0;
    38         }
    39         
    40         cin>>m;
    41         for(int i=0;i<m;i++)
    42         {
    43             cin>>op;
    44             
    45             if(op==1)
    46             {
    47                 cin>>place>>x;
    48                 
    49                 v[place-1].first=x;
    50                 v[place-1].second=i;
    51                 
    52                 quary[i]=-inf;
    53                 
    54             }
    55             else if(op==2)
    56             {
    57                 cin>>x;
    58                 
    59                 quary[i]=x;
    60                 
    61             }
    62         }
    63         int maxx=-inf;
    64         
    65         for(int i=m-1;i>=0;i--)
    66         {
    67             maxx=max(maxx,quary[i]);
    68             
    69             pre[i]=maxx;
    70         }
    71         
    72         for(int i=0;i<n;i++)
    73         {
    74             cout<<max(v[i].first,pre[v[i].second]);
    75             if(i==n-1)
    76                 cout<<endl;
    77             else
    78                 cout<<" ";        
    79         }
    80         
    81     }
    82     
    83     return 0;
    84 }
    大佬见笑,,
  • 相关阅读:
    Markdown基础语法
    Java是什么
    myBatis框架_关于怎么获得多表查询的总记录数
    关于Could not load driverClass ${jdbc.driverClassName}问题解决方案
    java中String与StringBuffer拼接的区别
    部分标签
    基础标签 网页分类
    入坑小开头
    完整版的OpenLDAP搭建全过程
    测试Linux下tcp最大连接数限制
  • 原文地址:https://www.cnblogs.com/xwl3109377858/p/11287929.html
Copyright © 2020-2023  润新知