//【優先度付きキュー(削除可能)】 #define _DEBUG 0 #include #include #include #include #define _HEAP_TYPE int//★型の確認必須 #define _HEAP_NUM_MAX (3000010)//削除をする場合は制約よりも確実に大きくなる★確認必須 //変数短縮 #define _TABLE_TOP &pq[0][0][0] #define _NUM_TOP &pqNum[0][0] #define _TABLE_MIN_ADD &pq[0][0][0] #define _TABLE_MIN_DEL &pq[0][1][0] #define _TABLE_MAX_ADD &pq[1][0][0] #define _TABLE_MAX_DEL &pq[1][1][0] #define _NUM_MIN_ADD &pqNum[0][0] #define _NUM_MIN_DEL &pqNum[0][1] #define _NUM_MAX_ADD &pqNum[1][0] #define _NUM_MAX_DEL &pqNum[1][1] //引数短縮 #define __PUSH_ADD &pq[0][0][0],&pqNum[0][0] #define __PUSH_DEL &pq[0][1][0],&pqNum[0][1] #define __MIN_TOP _HEAP_MIN,_TABLE_TOP,_NUM_TOP #define __MAX_TOP _HEAP_MAX,_TABLE_TOP,_NUM_TOP #define __MIN_ADD _HEAP_MIN,_TABLE_MIN_ADD,_NUM_MIN_ADD #define __MIN_DEL _HEAP_MIN,_TABLE_MIN_DEL,_NUM_MIN_DEL #define __MAX_ADD _HEAP_MAX,_TABLE_MAX_ADD,_NUM_MAX_ADD #define __MAX_DEL _HEAP_MAX,_TABLE_MAX_DEL,_NUM_MAX_DEL enum{ _HEAP_ADD=0, _HEAP_DEL, _HEAP_ADDDEL_NUM }; enum{ _HEAP_MIN=0, _HEAP_MAX, _HEAP_MINMAX_NUM }; void swap(_HEAP_TYPE *pa,_HEAP_TYPE *pb){_HEAP_TYPE tmp=*pa;*pa=*pb;*pb=tmp;} void heapInit(_HEAP_TYPE *table, int *num) { int clearsize = (num[_HEAP_ADD]>num[_HEAP_DEL] ? num[_HEAP_ADD]:num[_HEAP_DEL]); for(int i=0;i<4;i++){memset(table + i*_HEAP_NUM_MAX, 0, clearsize*sizeof(_HEAP_TYPE));*(num+i)=0;} } void swapMinUp(_HEAP_TYPE *table, int downindex) { while((downindex>>1) && *(table + (downindex>>1)) > *(table + downindex) ){ swap(table + (downindex>>1), table + downindex);downindex>>=1; } } void swapMaxUp(_HEAP_TYPE *table, int downindex) { while((downindex>>1) && *(table + (downindex>>1)) < *(table + downindex) ){ swap(table + (downindex>>1), table + downindex);downindex>>=1; } } void swapMinDown(_HEAP_TYPE *table, int endindex) { int upindex=1; while(upindex*2 < endindex+1){ int lindex, rindex, swapindex; if(upindex*2 == endindex){swapindex=(upindex<<1) + 0;} else{ lindex=(upindex<<1) + 0;rindex=(upindex<<1) + 1; swapindex=*(table+lindex)<*(table+rindex) ? lindex:rindex; } if(*(table+swapindex)<*(table+upindex))swap(table + upindex, table + swapindex); upindex=swapindex; } } void swapMaxDown(_HEAP_TYPE *table, int endindex) { int upindex=1; while(upindex*2 < endindex+1){ int lindex, rindex, swapindex; if(upindex*2 == endindex){swapindex=(upindex<<1) + 0;} else{ lindex=(upindex<<1) + 0;rindex=(upindex<<1) + 1; swapindex=*(table+lindex)>*(table+rindex) ? lindex:rindex; } if(*(table+swapindex)>*(table+upindex))swap(table + upindex, table + swapindex); upindex=swapindex; } } void heapPush(int minmax, _HEAP_TYPE *table, int *num, _HEAP_TYPE value) { (*num)++;*(table + *num) = value; if(2<=*num){ if(_HEAP_MIN==minmax)swapMinUp(table, *num); else swapMaxUp(table, *num); } } void heapPushMM(_HEAP_TYPE *table, int *num, _HEAP_TYPE value) { heapPush(_HEAP_MIN, table, num, value); //MIN heapPush(_HEAP_MAX, table + 2*_HEAP_NUM_MAX, num + 2, value);//MAX } _HEAP_TYPE heapPop(int minmax, _HEAP_TYPE *table, int *num) { swap(table + 1, table + *num);(*num)--; if(2<=*num){ if(_HEAP_MIN==minmax)swapMinDown(table, *num); else swapMaxDown(table, *num); }return 0; } _HEAP_TYPE heapOutput(int minmax, _HEAP_TYPE *table, int *num, bool *OK) { if(0==*num){*OK=false;return 0;} _HEAP_TYPE topValue=0, delValue=0; while(*num && *(num+1)){ topValue=*(table + 1);delValue=*(table + 1*_HEAP_NUM_MAX + 1); if(topValue==delValue){ heapPop(minmax, table, num); heapPop(minmax, table + 1*_HEAP_NUM_MAX, num + 1); } else break; }if(0==*num){*OK=false;return 0;} return *(table + 1); } _HEAP_TYPE heapPopMM(int minmax, _HEAP_TYPE *table, int *num, bool *OK) { _HEAP_TYPE popvalue; if(_HEAP_MIN==minmax){ //MINに削除するだけの個数が残っているか確認 if(0==*num){*OK=false;return 0;} //MINを削除し、MAXに予約を入れる popvalue=heapOutput(_HEAP_MIN, table, num, OK); if(*OK){ heapPop(_HEAP_MIN, table, num); (void)heapOutput(_HEAP_MAX, table + 2*_HEAP_NUM_MAX, num + 2, OK); if(*OK && 1<=*(num+2)){ //MINで削除した値を、MAXの削除予約に登録する heapPush(_HEAP_MAX, table + 3*_HEAP_NUM_MAX, num + 3, popvalue); } } }else{ //MAXに削除するだけの個数が残っているか確認 if(0==*(num+2)){*OK=false;return 0;} //MAXを削除し、MINに予約を入れる popvalue=heapOutput(_HEAP_MAX, table + 2*_HEAP_NUM_MAX, num + 2, OK); if(*OK){ heapPop(_HEAP_MAX, table + 2*_HEAP_NUM_MAX, num + 2); (void)heapOutput(_HEAP_MIN, table, num, OK); if(*OK && 1<=*num){ //MAXで削除した値を、MINの削除予約に登録する heapPush(_HEAP_MIN, table + 1*_HEAP_NUM_MAX, num + 1, popvalue); } } }if(!(*OK))return 0; return popvalue; } // heapPushMM(__PUSH_ADD, 2);//minとmaxに2を追加 // heapPushMM(__PUSH_DEL, 2);//minとmaxから2を削除(予約) // 結果min=heapOutput(__MIN_ADD, &OK);//追加対象のminのminを返す(minのmaxは取得不可) // 結果min=heapOutput(__MIN_DEL, &OK);//削除対象のminのminを返す(minのmaxは取得不可) // 結果max=heapOutput(__MAX_ADD, &OK);//追加対象のmaxのmaxを返す(maxのminは取得不可) // 結果max=heapOutput(__MAX_DEL, &OK);//追加対象のminのminを返す(minのmaxは取得不可) // 削除値=heapPopMM(__MIN_TOP, &OK);//minのminを削除(minのmaxは削除不可) // 削除値=heapPopMM(__MAX_TOP, &OK);//maxのmaxを削除(maxのminは削除不可) int main (void) { int scan;//scanf警告用 int ans=0; int i, j; int q=0; int pqNum[_HEAP_MINMAX_NUM][_HEAP_ADDDEL_NUM]={{_HEAP_NUM_MAX, _HEAP_NUM_MAX},{_HEAP_NUM_MAX, _HEAP_NUM_MAX}}; _HEAP_TYPE pq[_HEAP_MINMAX_NUM][_HEAP_ADDDEL_NUM][_HEAP_NUM_MAX]; heapInit(_TABLE_TOP, _NUM_TOP);//全0初期化 bool OK=true; int n,k,x;scan=scanf("%d%d%d",&n,&k,&x); int a[200010];for(i=0;itotal ? max:total; #if 0 printf("q=%d : %lld : total = %lld, max = %lld\n",q,sum,total,max); #endif } printf("%lld\n",max); // int min=1123456789; // while(i