Codeforces Round #576 (Div. 2) D - Welfare State

Posted xwl3109377858

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #576 (Div. 2) D - Welfare State相关的知识,希望对你有一定的参考价值。

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("\n");
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 

 

以上是关于Codeforces Round #576 (Div. 2) D - Welfare State的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #576 (Div. 2) D. Welfare State

codeforces 576c// Points on Plane// Codeforces Round #319(Div. 1)

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)

Codeforces 576C. Points on Plane(构造)