1. 程式人生 > >北京集訓DAY5

北京集訓DAY5

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