吐个糟,尼玛今天被虐成狗了,一题都没搞出来,这题搞了N久居然还是搞不出来,一直TLE,最后还是参考别人代码才领悟的,思路就这么简单,
就是不会转弯,看着模板却不会改,艹,真怀疑自己是不是个笨蛋
题意:求n维空间的最远哈曼顿距离。给出n和k,下面n个操作,0表示添加一个k维空间的点,然后给出该点坐标,1 x表示删除第x个操作给出的点
,对于每个操作都输出最远哈曼顿距离,n《=60000,k《=5。
分析:最远曼哈顿距离的模板是直接求D维空间n个点的,复杂度是O(n*2^D),而该题要求每次加一个点就求一次最远曼哈顿距离,如果直接套模板
的话复杂度是O(n^2*2^D),这已经相当高了,再加上有删点操作,所以肯定是TLE的,我刚开始就是这么做的,应该要进行优化。
其实我们可以用堆或优先队列来优化,根据最远曼哈顿距离的求法(不懂得可以百度),其实就是找出每个点去绝对值后的形式,然后枚举所有的
组合再求出最大值,所以我们可以建立一个最小堆和最大堆,每加入一个点就枚举该点去绝对值后的形式(总共有2^D-1种),将其加入到对应的
两个堆中,将最大堆和最小堆堆顶元素相减,其实就是两点之间的曼哈顿距离了,最后枚举所有的形式,找最大值就行了。
对于删点操作,用一个数组p[]标记一下,在枚举形式求最大值时,判断一下堆顶元素是否是已被删的点,如果是的话,出堆就行了
还有就是求距离的时候不要像模板那样用二维数组,不然会爆内存的,我就是这样MLE了两次 =_=||
代码如下:
1 #include<stdio.h> 2 #include<vector> 3 #include<string.h> 4 #include<queue> 5 using namespace std; 6 int coe[5],minx[32][2],maxx[32][2],pt[60010]; 7 int p[60010]; 8 int minp,maxp,ans,m; 9 struct node1{ 10 int s,i; 11 bool operator <(const node1 &a)const{ 12 return s<a.s; 13 } 14 }; 15 struct node2{ 16 int s,i; 17 bool operator<(const node2 &a)const{ 18 return s>a.s; 19 } 20 }; 21 priority_queue<node1> q1[32]; 22 priority_queue<node2> q2[32]; 23 node1 x; 24 node2 y; 25 void GetD(int D){ 26 int s,i,dis,tot=(1<<D); 27 for(s=0;s<tot;s++) 28 { 29 for(i=0;i<D;i++) 30 if(s&(1<<i)) 31 coe[i]=-1; 32 else 33 coe[i]=1; 34 dis=0; 35 for(i=0;i<D;i++) 36 dis=dis+coe[i]*pt[i]; 37 x.s=dis; 38 x.i=m; 39 y.s=dis; 40 y.i=m; 41 q1[s].push(x); 42 q2[s].push(y); 43 } 44 } 45 void Solve(int D) 46 { 47 int s,tot=(1<<D); 48 int tmp; 49 for(s=0;s<tot;s++) 50 { 51 while(!p[q1[s].top().i]&&!q1[s].empty()) 52 q1[s].pop(); 53 while(!p[q2[s].top().i]&&!q2[s].empty()) 54 q2[s].pop(); 55 maxx[s][0]=q1[s].top().s; 56 maxx[s][1]=q1[s].top().i; 57 minx[s][0]=q2[s].top().s; 58 minx[s][1]=q2[s].top().i; 59 } 60 ans=0; 61 for(s=0;s<tot;s++) 62 { 63 tmp=maxx[s][0]-minx[s][0]; 64 if(tmp>ans) 65 { 66 ans=tmp; 67 maxp=maxx[s][1]; 68 minp=minx[s][1]; 69 } 70 } 71 printf("%d ",ans); 72 } 73 int main() 74 { 75 int s,tot,n,k,i,od,x,j; 76 while(scanf("%d%d",&n,&k)!=EOF) 77 { 78 memset(p,0,sizeof(p)); 79 minp=maxp=-1; 80 tot=(1<<k); 81 for(s=0;s<tot;s++) 82 { 83 while(!q1[s].empty()) 84 q1[s].pop(); 85 while(!q2[s].empty()) 86 q2[s].pop(); 87 } 88 m=-1; 89 for(i=0;i<n;i++) 90 { 91 scanf("%d",&od); 92 m++; 93 if(od==0) 94 { 95 p[i]=1; 96 for(j=0;j<k;j++) 97 scanf("%d",&pt[j]); 98 GetD(k); 99 Solve(k); 100 } 101 else 102 { 103 scanf("%d",&x); 104 p[x-1]=0; 105 if((x-1)==minp||(x-1)==maxp) 106 Solve(k); 107 else 108 printf("%d ",ans); 109 } 110 } 111 } 112 return 0; 113 }