Codeforces Global Round 7E(线段树,贪心)
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 long long a[300007],q[300007],b[300007]; 5 long long mx[1200007],mxid[1200007]; 6 long long lz[1200007]; 7 void up(long long rt){ 8 if(mx[rt<<1]>=mx[rt<<1|1]){ 9 mx[rt]=mx[rt<<1]; 10 mxid[rt]=mxid[rt<<1]; 11 } 12 else{ 13 mx[rt]=mx[rt<<1|1]; 14 mxid[rt]=mxid[rt<<1|1]; 15 } 16 } 17 void down(long long rt){ 18 lz[rt<<1]+=lz[rt]; 19 lz[rt<<1|1]+=lz[rt]; 20 mx[rt<<1]+=lz[rt]; 21 mx[rt<<1|1]+=lz[rt]; 22 lz[rt]=0; 23 } 24 void build(long long rt,long long l,long long r){ 25 if(l==r){ 26 mx[rt]=0; 27 mxid[rt]=l; 28 return ; 29 } 30 build(rt<<1,l,(l+r)>>1); 31 build(rt<<1|1,((l+r)>>1)+1,r); 32 up(rt); 33 } 34 void update(long long rt,long long l,long long r,long long L,long long R,long long k){ 35 if(L>R) 36 return ; 37 if(L<=l&&r<=R){ 38 lz[rt]+=k; 39 mx[rt]+=k; 40 return ; 41 } 42 down(rt); 43 if(L<=((l+r)>>1)) 44 update(rt<<1,l,(l+r)>>1,L,R,k); 45 if(R>((l+r)>>1)) 46 update(rt<<1|1,((l+r)>>1)+1,r,L,R,k); 47 up(rt); 48 } 49 long long cmx,cid; 50 void query(long long rt,long long l,long long r,long long L,long long R){ 51 if(L<=l&&r<=R){ 52 if(mx[rt]>cmx){ 53 cmx=mx[rt]; 54 cid=mxid[rt]; 55 } 56 return ; 57 } 58 down(rt); 59 if(L<=((l+r)>>1)) 60 query(rt<<1,l,(l+r)>>1,L,R); 61 if(R>((l+r)>>1)) 62 query(rt<<1|1,((l+r)>>1)+1,r,L,R); 63 } 64 int main(){ 65 ios::sync_with_stdio(false); 66 cin.tie(NULL); 67 cout.tie(NULL); 68 int n; 69 cin>>n; 70 for(int i=1;i<=n;++i){ 71 cin>>a[i]; 72 b[a[i]]=i;//存放每个数出现的位置 73 } 74 for(int i=1;i<=n;++i) 75 cin>>q[i]; 76 build(1,1,n); 77 int ans=n; 78 update(1,1,n,1,b[n],1);//最大值出现的位置以及左边全部+1,意为这些位置及右侧有一个数不比它们小(此时还没有加入炸弹) 79 for(int i=1;i<=n;++i){ 80 cout<<ans<<" "; 81 update(1,1,n,1,q[i],-1);//每次加入一个炸弹,在炸弹位置及左侧全部-1,如果所有点都不为正值,说明当前ans非法,因为所有大于等于它的数位置及其右侧都有至少x颗炸弹(x为这个数是第几大的数) 82 while(mx[1]<=0){ 83 --ans;//答案-1,重新检测是否合法 84 update(1,1,n,1,b[ans],1);//-1以后所有ans及其左侧的数位置及其右侧都多了一个不比自己小的数 85 } 86 } 87 return 0; 88 }
保持热爱 不懈努力
不试试看怎么知道会失败呢(划掉)
世上无难事 只要肯放弃(划掉)