"BZOJ4167" Forever Bamboo Shoots picking tiles + tree-like array

Source: Internet
Author: User

"BZOJ4167" Forever Bamboo Shoots picking

The puzzle: We consider how many point pairs (A, B) satisfy the difference between A and B. is the smallest of [b]. Think it is random data, so the number of points may be very small, measured is O (n) level, then we know there are so many possible to contribute to the point pair, how to find out?

Consider chunking, because all numbers are in [1,n], and we can preprocess the entire block to the minimum difference of all numbers for each block. Then enumerate each point from right to left, and then enumerate all the blocks on it, and if the difference between the block and the current number is smaller than the previous one, then the violence is swept through the block. At the same time, we need to know if we already have such a pair, which is completely contained by the current point pair and has a smaller difference. This can be done in a tree-like array.

Finally, we get all the point pairs, the problem becomes a line on the axis to select the intersection of K-cross segments, so that the segment weights and minimum. Run a DP on the line.

#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include < algorithm>using namespace Std;const int maxn=60010;int n,m,b,cnt,minn;int s[maxn],v[maxn],p[maxn];int cls[250][ Maxn],f[2][maxn],to[500000],next[500000],head[maxn],val[500000];int Rd () {int Ret=0,f=1;char gc=getchar (); while (GC < ' 0 ' | | Gc> ' 9 ') {if (gc== '-') F=-f;gc=getchar ();} while (gc>= ' 0 ' &&gc<= ' 9 ') ret=ret*10+gc-' 0 ', Gc=getchar (); return ret*f;} int z (int x) {return x>0?x:-x;} void Updata (int x,int val) {for (int i=x;i<=n;i+=i&-i) s[i]=min (s[i],val);} int query (int x) {int i,ret=1<<30;for (i=x;i;i-=i&-i) ret=min (Ret,s[i]); return ret;} void Test (int a,int b) {int c=z (V[b]-v[a]), A++,b++,minn=min (Minn,c), if (query (b) <=c) return, Updata (b,c); To[cnt]=a, val[cnt]=c,next[cnt]=head[b],head[b]=cnt++;} int main () {//freopen ("bz4168.in", "R", stdin), N=rd (), M=rd (), B=ceil (sqrt (n)); int i,j,k,last;for (i=0;i<n;i++) v[i] =rd (); memset (Cls,0x3f,sizeof (CLS)); memset (s,0x3f,sizeof (s));for (i=0;i<n;i+=b) {for (j=i;j<i+b&&j<n;j++) p[v[j]]=1;for (last=-1<<30,j=1;j<=n;j++) cls[ I/b][j]=min (Cls[i/b][j],j-last), Last=p[j]?j:last;for (last=1<<30,j=n;j>=1;j--) cls[i/B][j]=min (Cls[i/B] [J],last-j], Last=p[j]?j:last;for (j=i;j<i+b&&j<n;j++) p[v[j]]=0;} memset (head,-1,sizeof (head)); for (i=n-1;i>=0;i--) {minn=1<<30;for (j=i+1;j<i/b*b+b&&j<n;j+ +) if (V[j]!=v[i]&&z (V[j]-v[i]) <minn) test (I,J); for (j=i/b+1;j*b<n;j++) if (Cls[j][v[i]]<minn) for (k =j*b;k<j*b+b&&k<n;k++) if (V[k]!=v[i]&&z (V[k]-v[i]) <minn) test (i,k);} for (k=1;k<=m;k++) {for (i=0;i<=n;i++) f[k&1][i]=1<<30;for (i=1;i<=n;i++) {f[k&1][i]=f[k& 1][i-1];for (J=head[i];j!=-1;j=next[j]) f[k&1][i]=min (f[(k&1) ^1][to[j]-1]+val[j],f[k&1][i]);}} printf ("%d\n", F[m&1][n]); return 0;}

BZOJ4167 Forever Bamboo Shoots picking block + tree-like array

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.