北京集訓DAY5
阿新 • • 發佈:2017-10-11
lower 大於 pan 數據 git getc 前綴和 搜索 cstring
1 /* 2 首先我們知道 2的連續的整數次冪可以構成連續的一段區間 3 例如 1 2 4 可以用來表示 1-7 4 如果想要表示8的話 第四個數只能為8 如果大於8 那麽8則無法表示 5 6 本題同理 我們假設 前k個數可以表示 1-sum 則sum為前k個數的前綴和 7 如果第k+1個數大於sum 在無法表示sum+1 8 輸出即可 9 */ 10 #include <cstdio> 11 #include <cctype> 12 #include <iostream> 13代碼#include <algorithm> 14 15 using namespace std; 16 17 typedef long long LL; 18 19 const int N=1e5+5; 20 21 int n,a[N]; 22 23 LL sum; 24 25 bool flag; 26 27 inline void read(int&x) { 28 int f=1;register char c=getchar(); 29 for(x=0;!isdigit(c);c==‘-‘&&(f=-1),c=getchar()); 30 for(;isdigit(c);x=x*10+c-48,c=getchar()); 31 x=x*f; 32 } 33 34 int hh() { 35 freopen("lost.in","r",stdin); 36 freopen("lost.out","w",stdout); 37 read(n); 38 for(int i=1;i<=n;++i) read(a[i]); 39 std::sort(a+1,a+n+1); 40 for(int i=1;i<=n;++i) {41 if(a[i]>sum+1) { 42 cout<<sum+1<<endl; 43 flag=true; 44 break; 45 } 46 else sum+=(LL)a[i]; 47 } 48 if(!flag) cout<<sum+1<<endl; 49 return 0; 50 } 51 52 int sb=hh(); 53 int main(int argc,char**argv){;}
1 /* 2 對於前60的數據 利用除法分塊可以輕松跑過 3 復雜度為 O(srqt(n)) 4 但是對於1e18 復雜度達到 1e9 除法分塊就不行了 5 6 我們可以先打一個表 看看有沒有規律 7 據說是有一個O(1) 出解的規律 但是我沒有看出來。 8 所以用的另一個規律 先二分 再判斷ans 9 */ 10 #include <cctype> 11 #include <cstdio> 12 #include <iostream> 13 14 using namespace std; 15 16 typedef unsigned long long LL; 17 18 LL n,ans; 19 20 int hh() { 21 freopen("div.in","r",stdin); 22 freopen("div.out","w",stdout); 23 cin>>n; 24 LL l=0,r=1000000000; 25 while(l+1<r) { 26 LL mid=(l+r)>>1; 27 if(((mid*mid)+mid)-1>=n) r=mid; 28 else l=mid; 29 } 30 LL p=r-1; 31 LL sum=(p*p)+p-1+r; 32 if(n<=sum) ans=r*2-2; 33 else ans=r*2-1; 34 cout<<ans<<endl; 35 fclose(stdin); 36 fclose(stdout); 37 return 0; 38 } 39 40 int sb=hh(); 41 int main(int argc,char**argv) {;}代碼
1 /* 2 沒有意識到這題的復雜度 是2^n 3 所以打了一個 最裸的暴力拿了60 (其實 看到數據範圍我也打不出正解) 4 5 正解是一種不太常用的思想 6 叫做 meet in middle 7 對於極限數據 n<=30 8 2^30 接近於1e9 這是無法跑出來的 9 所以利用 meet in middle 10 把搜索分成兩部分 前一部分 只搜前2^15種狀態 11 後一部分搜 後2^15種狀態 然後兩部分合並 12 總復雜度 O(2*2^(n/2)) 13 */ 14 #include<cstdio> 15 #include<cstring> 16 #include<algorithm> 17 #include<vector> 18 19 using namespace std; 20 21 int tt; 22 23 int n,m; 24 25 int v[35]; 26 27 double p[35]; 28 29 double ans[35]; 30 31 vector<pair<int,double> > sta[35]; 32 33 int main(){ 34 freopen("diamond.in","r",stdin); 35 freopen("diamond.out","w",stdout); 36 scanf("%d%d",&n,&m); 37 for(int i=1,x;i<=n;i++){ 38 scanf("%d%d",&v[i],&x); 39 p[i]=x/100.; 40 } 41 for(int i=0;i<=n;i++) sta[i].clear(); 42 int an=(n/2.5)+1; 43 int bn=n-an; 44 for(int st=0;st<1<<bn;st++){ 45 double nowp=1; 46 int cnt=0,money=0; 47 for(int i=0;i<bn;i++){ 48 if((st>>i)&1){ 49 money+=v[n-i]; 50 nowp*=p[n-i]; 51 } 52 else 53 cnt++,nowp*=(1-p[n-i]); 54 } 55 sta[cnt].push_back(make_pair(money,nowp)); 56 } 57 for(int i=0;i<=n;i++){ 58 sort(sta[i].begin(),sta[i].end()); 59 for(int j=1;j<sta[i].size();j++) sta[i][j].second+=sta[i][j-1].second; 60 } 61 for(int st=0;st<1<<an;st++){ 62 double nowp=1; 63 int cnt=0,money=0; 64 for(int i=0;i<an;i++){ 65 if((st>>i)&1){ 66 money+=v[i+1]; 67 nowp*=p[i+1]; 68 } 69 else cnt++,nowp*=(1-p[i+1]); 70 } 71 for(int i=0;i<=bn;i++){ 72 int L = m-money; 73 vector<pair<int,double> >::iterator it = lower_bound(sta[i].begin(),sta[i].end(),make_pair(L,-1.)); 74 double tmp = sta[i].back().second; 75 if(it!= sta[i].begin()){ 76 it--; 77 tmp-=it->second; 78 } 79 ans[cnt+i] += tmp*nowp; 80 } 81 } 82 for(int i=0;i<=n;i++) printf("%.3f\n",ans[i]); 83 fclose(stdout); 84 return 0; 85 }代碼
北京集訓DAY5