Test instructions: The sequence length is n,m operations (n<=50000,m<=500000), each operation will be the interval [si,ti] from small to large order, for at least a few operations to make the last number of the sequence and after all operations equal;
Idea: Choose the least operation to get the best solution, generally adopt DP;
Assuming that the 1th number of the original sequence is the maximum, Dp[j] indicates that the maximum value moved to the J position requires at least one operand;
Initial order Dp[1]=0,dp[j]=inf (J>1);
For each I, there is Dp[ti]=min (Dp[ti],min (Dp[j] (si<=j<=ti)) +1);
If the complexity is O (nm), it will time out, so the minimum value is the use of Segment tree optimization (another array);
The segment tree is updated by a single point, and the interval is extremum;
#include <cstdio>#include<cstring>#include<algorithm>using namespacestd;#defineINF 0x3f3f3f3fintdp[5000100];intnum[5000100];intn,m;ints[5000100],t[5000100];voidBuildintLintRintPOS) {Num[pos]=dp[pos]=inf; if(l==R) { return; } intMid= (L+R)/2; Build (L,mid,pos*2); Build (Mid+1, r,pos*2+1);}voidUpdateintPintValintLintRintPOS) { if(Dp[pos]>val) dp[pos]=Val; if(l!=R) { intMid= (L+R)/2; if(p<=mid) Update (p,val,l,mid,pos*2); Else if(mid<p) Update (p,val,mid+1, r,pos*2+1); }}intQueryintLintRintLintRintPOS) { if(l<=l&&r<=s) { returnDp[pos]; } intMid= (L+R)/2; if(R<=mid)returnQuery (l,r,l,mid,pos*2); Else if(mid<l)returnQuery (l,r,mid+1, r,pos*2+1); Else{ intt1,t2; T1=query (l,r,l,mid,pos*2); T2=query (l,r,mid+1, r,pos*2+1); returnmin (t1,t2); }}intMain () {inti,j,k; while(SCANF ("%d%d", &n,&m)! =EOF) {Build (1N1); for(i=0; i<m;i++) {scanf ("%d%d",&s[i],&T[i]); } num[1]=0; Update (1,0,1N1); for(i=0; i<m;i++){ intV=min (Num[t[i]],query (s[i],t[i]+1,1N1)+1); Num[t[i]]=v; Update (T[I],V,1N1); } printf ("%d\n", Num[n]); } return 0;}
POJ 1769 minimizing maximizer (dp+ segment tree)