hihocoder#1384/北京网络赛2016 Genius ACM 归并排序+倍增

Posted mygirlfriends

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hihocoder#1384/北京网络赛2016 Genius ACM 归并排序+倍增相关的知识,希望对你有一定的参考价值。

考虑固定l,每次查找符合的r,每次倍增长度p,用归并排序将后面的可行的部分归并进去,时间复杂度O(nlogn),不用读入挂就T了

技术分享图片
  1 /* ***********************************************
  2 Author        :BPM136
  3 Created Time  :2018/7/15 15:37:13
  4 File Name     :1384.cpp
  5 ************************************************ */
  6 
  7 #include<iostream>
  8 #include<cstdio>
  9 #include<algorithm>
 10 #include<cstdlib>
 11 #include<cmath>
 12 #include<cstring>
 13 #include<vector>
 14 using namespace std;
 15 
 16 typedef long long ll;
 17 
 18 namespace fastIO{  
 19     #define BUF_SIZE 100000  
 20     #define OUT_SIZE 100000  
 21     //fread->read  
 22     bool IOerror=0;  
 23     inline char nc(){  
 24         static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;  
 25         if (p1==pend){  
 26             p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);  
 27         if (pend==p1){IOerror=1;return -1;}  
 28         //{printf("IO error!
");system("pause");for (;;);exit(0);}  
 29     }  
 30     return *p1++;  
 31 }  
 32 inline bool blank(char ch){return ch== ||ch==
||ch==
||ch==	;}  
 33 inline void read(int &x){  
 34     bool sign=0; char ch=nc(); x=0;  
 35     for (;blank(ch);ch=nc());  
 36     if (IOerror)return;  
 37     if (ch==-)sign=1,ch=nc();  
 38     for (;ch>=0&&ch<=9;ch=nc())x=x*10+ch-0;  
 39     if (sign)x=-x;  
 40 }  
 41 inline void read(ll &x){  
 42     bool sign=0; char ch=nc(); x=0;  
 43     for (;blank(ch);ch=nc());  
 44     if (IOerror)return;  
 45     if (ch==-)sign=1,ch=nc();  
 46     for (;ch>=0&&ch<=9;ch=nc())x=x*10+ch-0;  
 47     if (sign)x=-x;  
 48 }  
 49 inline void read(double &x){  
 50     bool sign=0; char ch=nc(); x=0;  
 51     for (;blank(ch);ch=nc());  
 52     if (IOerror)return;  
 53     if (ch==-)sign=1,ch=nc();  
 54     for (;ch>=0&&ch<=9;ch=nc())x=x*10+ch-0;  
 55     if (ch==.){  
 56         double tmp=1; ch=nc();  
 57         for (;ch>=0&&ch<=9;ch=nc())tmp/=10.0,x+=tmp*(ch-0);  
 58     }  
 59     if (sign)x=-x;  
 60 }  
 61 inline void read(char *s){  
 62     char ch=nc();  
 63     for (;blank(ch);ch=nc());  
 64     if (IOerror)return;  
 65     for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;  
 66     *s=0;  
 67 }  
 68 inline void read(char &c){  
 69     for (c=nc();blank(c);c=nc());  
 70     if (IOerror){c=-1;return;}  
 71 } 
 72 #undef OUT_SIZE  
 73 #undef BUF_SIZE  
 74 }; using namespace fastIO;
 75 
 76 const int N = 500005;
 77 
 78 ll sqr(ll x) { return x*x; }
 79 
 80 int t[N];
 81 int merge(int a[],int n,int b[],int m) {
 82     int ret=0;
 83     int l1=1,l2=1;
 84     while(l1<=n && l2<=m) {
 85         if(a[l1]<b[l2]) {
 86             t[++ret]=a[l1];
 87             l1++;
 88         } else {
 89             t[++ret]=b[l2];
 90             l2++;
 91         }
 92     }
 93     while(l1<=n) {
 94         t[++ret]=a[l1];
 95         l1++;
 96     }
 97     while(l2<=m) {
 98         t[++ret]=b[l2];
 99         l2++;
100     }
101     for(int i=1;i<=ret;i++) a[i]=t[i];
102     return ret;
103 }
104 
105 int n,m;
106 ll LIM;
107 int a[N];
108 int b[N];
109 int c[N];
110 
111 bool check(int a[],int l,int r,int L) {
112     ll sum=0;
113     for(int i=l,j=r;i<=j && (i-l+1)<=L;i++,j--) {
114         sum+=sqr((ll)a[i]-a[j]);
115         if(sum>LIM) return 0;
116     }
117     return 1;
118 }
119 
120 void ARR_OUT(int arr[],int num) {
121     for(int i=1;i<=num;i++) cerr<<arr[i]<< ; cerr<<endl;
122 }
123 
124 int main() {
125     int T;
126     read(T);
127     while(T--) {
128         //scanf("%d%d%d",&n,&m,&LIM);
129         read(n); read(m); read(LIM);
130         for(int i=1;i<=n;i++) read(a[i]);//scanf("%d",&a[i]);
131         int ans=0;
132         int l=1,r=l,p=1;
133         while(l<=n) {
134             b[1]=a[l];
135             while(p) {
136                 if(r+p>n) {
137                     p>>=1;
138                     continue;
139                 }
140                 int i,j;
141                 for(i=r+1,j=1;i<=r+p;i++,j++) c[j]=a[i];
142                 sort(c+1,c+j);
143                 int num=merge(c,j-1,b,r-l+1);
144                 if(check(c,1,num,m)) {
145                     for(int i=1;i<=num;i++) b[i]=c[i];
146                     r=r+p;
147                     p<<=1;
148                 } else {
149                     p>>=1;
150                 }
151             }
152             ans++;
153             l=r+1; r=l; p=1;
154         }
155         printf("%d
",ans);
156     }
157     return 0;
158 }
View Code

 

以上是关于hihocoder#1384/北京网络赛2016 Genius ACM 归并排序+倍增的主要内容,如果未能解决你的问题,请参考以下文章

Hihocoder1388 2016年北京网络赛 FFT

(每日一题)2016 北京ICPC网络赛G hihocoder 1388 (中国剩余定理 + NTT)

hihoCoder 1389 Sewage Treatment 二分+网络流+优化 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)

hihoCoder 1392 War Chess 模拟 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)

hihoCoder 1391 Countries 预处理+排序+堆 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛)

hihoCoder 1383 : The Book List 北京网络赛