分块90分。 By AutSky_JadeK 【重点在下面】
1 #include<cstdio> 2 #include<cmath> 3 using namespace std; 4 #define N 1000001 5 #define INF 2147483647 6 #define min(a,b) (((a)<(b))?(a):(b)) 7 int n,m,a[N],sum,sz,l[8001],r[8001],minv[8001],delta[8001],num[N],x,y,v; 8 int ans,re2; 9 int Res;char C; 10 inline int G() 11 { 12 Res=0;C='*'; 13 while(C<'0'||C>'9')C=getchar(); 14 while(C>='0'&&C<='9'){Res=Res*10+(C-'0');C=getchar();} 15 return Res; 16 } 17 void makeblock() 18 { 19 sz=(int)sqrt((double)n*0.1); if(!sz) sz=1; 20 for(sum=1;sum*sz<n;sum++) 21 { 22 l[sum]=r[sum-1]+1; r[sum]=sum*sz; 23 minv[sum]=INF; 24 for(int i=l[sum];i<=r[sum];i++) {minv[sum]=min(minv[sum],a[i]); num[i]=sum;} 25 } 26 l[sum]=r[sum-1]+1; r[sum]=n; 27 minv[sum]=INF; 28 for(int i=l[sum];i<=r[sum];i++) {minv[sum]=min(minv[sum],a[i]); num[i]=sum;} 29 } 30 inline void work(const int &L,const int &R) 31 { 32 minv[num[L]]=INF; 33 for(int i=L;i<=R;i++) a[i]-=v; 34 for(int i=l[num[L]];i<=r[num[L]];i++) minv[num[L]]=min(minv[num[L]],a[i]); 35 } 36 inline void update() 37 { 38 if(num[x]==num[y]) work(x,y); 39 else 40 { 41 work(x,r[num[x]]); work(l[num[y]],y); 42 for(int i=num[x]+1;i<num[y];i++) delta[i]-=v; 43 } 44 } 45 inline int query() 46 { 47 ans=INF; 48 if(num[x]==num[y]) {for(int i=x;i<=y;i++) ans=min(ans,a[i]+delta[num[x]]); } 49 else 50 { 51 for(int i=x;i<=r[num[x]];i++) ans=min(ans,a[i]+delta[num[x]]); 52 for(int i=num[x]+1;i<num[y];i++) ans=min(ans,minv[i]+delta[i]); 53 for(int i=l[num[y]];i<=y;i++) ans=min(ans,a[i]+delta[num[y]]); 54 } return ans; 55 } 56 int main() 57 { 58 n=G(); m=G(); 59 for(int i=1;i<=n;i++) a[i]=G(); 60 makeblock(); 61 for(int i=1;i<=m;i++) 62 { 63 v=G(); x=G(); y=G(); 64 if(query()<v) 65 { 66 printf("-1 %d ",i); 67 return 0; 68 } 69 else update(); 70 } 71 puts("0"); 72 return 0; 73 }
分块 常数优化 100分。 By faebdc 金牌爷の力Orzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1 #include<cstdio> 2 #include<cmath> 3 using namespace std; 4 #define N 1000001 5 #define INF 2147483647 6 int n,m,a[N],sum,sz,hf,l[3001],r[3001],minv[3001],delta[3001],num[N],x,y,v; 7 int ans,re2; 8 int Res;char C; 9 inline int G() 10 { 11 Res=0;C='*'; 12 while(C<'0'||C>'9')C=getchar(); 13 while(C>='0'&&C<='9'){Res=(Res<<3)+(Res<<1)+C-'0';C=getchar();} 14 return Res; 15 } 16 void makeblock() 17 { 18 sz=(int)sqrt((double)n*0.125); if(!sz) sz=1; 19 hf=sz>>1; 20 for(sum=1;sum*sz<n;sum++) 21 { 22 l[sum]=r[sum-1]+1; r[sum]=sum*sz; 23 minv[sum]=INF; 24 for(int i=l[sum];i<=r[sum];i++) {if(minv[sum]>a[i])minv[sum]=a[i]; num[i]=sum;} 25 } 26 l[sum]=r[sum-1]+1; r[sum]=n; 27 minv[sum]=INF; 28 for(int i=l[sum];i<=r[sum];i++) {if(minv[sum]>a[i])minv[sum]=a[i]; num[i]=sum;} 29 } 30 inline void work(const int &L,const int &R) 31 { 32 int *t=&(minv[num[L]]); 33 *t=INF; 34 int *z; 35 for(int i=L,*z=a+i;i<=R;i++,z++) {*z-=v;if(*t>*z)*t=*z;} 36 for(int i=r[num[L]],*z=a+i;i>R;i--,z--) if(*t>*z)*t=*z; 37 for(int i=l[num[L]],*z=a+i;i<L;i++,z++) if(*t>*z)*t=*z; 38 } 39 inline int update() 40 { 41 if(num[x]==num[y]) {work(x,y);return minv[num[x]]+delta[num[x]];} 42 work(x,r[num[x]]); work(l[num[y]],y); 43 int z; 44 if(minv[num[x]]+delta[num[x]]>minv[num[y]]+delta[num[y]]) 45 z=minv[num[y]]+delta[num[y]]; 46 else 47 z=minv[num[x]]+delta[num[x]]; 48 for(int i=num[x]+1;i<num[y];i++) {delta[i]-=v;if(z>minv[i]+delta[i])z=minv[i]+delta[i];} 49 return z; 50 } 51 int main() 52 { 53 n=G(); m=G(); 54 for(int i=1;i<=n;i++) a[i]=G(); 55 makeblock(); 56 for(int i=1;i<=m;i++) 57 { 58 v=G(); x=G(); y=G(); 59 int z=update(); 60 if(z<0) 61 { 62 printf("-1 %d ",i); 63 return 0; 64 } 65 } 66 puts("0"); 67 return 0; 68 }