#576ラウンドCodeforces D(本部2。) - 福祉国家

#576(本部2)ラウンドCodeforces

 

D - 福祉国家

n個の市民と国があります。それらのi番目のは最初のAIお金を持っています。政府は、厳密にその市民の富を制御します。市民が買い物をするか、いくつかのお金を稼いでいるときはいつでも、彼らは、彼らが現在持っているお金の量を言及する社会サービスへの領収書を送信する必要があります。

支払いの後、彼らは正確にXお金を持っているように、xがそれに応じて支払われるより厳密に少ないお金を持っているすべての市民:たまに政府が貧困層への支払いを行います。この場合、市民は領収書を送信しません。

領収書や支払い:あなたはすべての市民の最初の富とすべてのイベントのログを知っています。すべてのイベントの後、各市民が持っているお金の量を復元します。

入力

市民のNUMER - 最初の行は、単一の整数n(^ 51≤n≤2⋅10)を含有します。

市民の初期残高 - 次の行には、n個の整数のA1、A2、...、(0≤ai≤10^ 9)が含まれています。

イベントの数 - 次の行は、単一の整数q(^ 51≤q≤2⋅10)を含有します。

次のqラインの各々は、単一のイベントが含まれています。イベントは、年代順に記載されています。

各イベントは、1つのピクセル(1≤p≤n、^ 90≤x≤10)、または2×(^ 90≤x≤10)のいずれかとして記載されています。最初のケースでは、p番目の人のバランスがxに等しくなる領収書を持っています。後者の場合では、パラメータxとのペイオフを持っています。

出力

印刷n個の整数 - すべてのイベントの後にすべての市民の残高。

入力

4

1 2 3 4

3

2 3

1 2 2

2 1

出力

3 2 3 4

入力

5

3 50 2 1 10

3

1 2 0

2 8

1 3 20

出力

8 8 20 8 10

注意

次のように最初の例で残高は変更:1 2 3 4→3 3 3 4→3 2 3 4→3 2 3 4

3 50 2 1 10→3 0 2 1 10→8 8 8 8 10→8 8 20 8 10:次のように第2の例では残高は変更します

 

 

题意:题目意思就是给你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 }

 

おすすめ

転載: www.cnblogs.com/xwl3109377858/p/11287929.html