北京集训②DAY1 Afternoon

来源:互联网 发布:配置windows update%0 编辑:程序博客网 时间:2024/05/16 12:31

对于三个点 a b c  有两个边权 x y

有结论 min( (a+b)/x , (b+c)/y ) < (a+b+c)/(x+y) 

由结论推广出去 三个点一定比四个点优 四个点一定比五个点优 ...............

我们可以得到结论 由两个点和一个边权得到的值最优 

 1 #include <cstdio> 2 #include <cctype> 3 #include <vector> 4  5 const int MAXN=100010; 6  7 int n,m; 8  9 int a[MAXN];10 11 struct node {12     int to;13     int val;14     node(int to,int val):to(to),val(val) {}15 };16 17 std::vector<node> Graph[MAXN]; 18 19 inline void read(int&x) {20     int f=1;register char c=getchar();21     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());22     for(;isdigit(c);x=x*10+c-48,c=getchar());23     x=x*f;24 }25 26 int hh() {27     freopen("graph.in","r",stdin);28     freopen("graph.out","w",stdout);29     read(n);read(m);30     for(int i=1;i<=n;++i) read(a[i]);31     for(int x,y,v,i=1;i<=m;++i) {32         read(x);read(y);read(v); 33         Graph[x].push_back(node(y,v));34         Graph[y].push_back(node(x,v));35     }36     double ans=.0;37     for(int i=1;i<=n;++i) {38         for(int j=0;j<Graph[i].size();++j) {39             int v=Graph[i][j].to;40             double val=(double)(a[i]+a[v])/Graph[i][j].val;41             if(ans<val) ans=val;42         }43     }44     printf("%.2lf\n",ans);45     fclose(stdin);46     fclose(stdout);47     return 0;48 }49 50 int sb=hh();51 int main(int argc,char**argv) {;}
代码

贪心 枚举高度 统计最小的宽度 

当身高>x 宽度<=x 一定躺下

   身高<=x 宽度>x 一定不会躺下

当身高,宽度<=x 

1丶 身高>宽度 一定不躺下

2丶 可以躺下 宽度-身高的值越大越好 (记录sort取大的数)

 1 #include <cstdio> 2 #include <cctype> 3 #include <algorithm> 4  5 const int MAXN=1010; 6  7 int n,ans,sum; 8  9 int w[MAXN],h[MAXN],data[MAXN],Nw[MAXN],Nh[MAXN];10 11 inline void read(int&x) {12     int f=1;register char c=getchar();13     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());14     for(;isdigit(c);x=x*10+c-48,c=getchar());15     x=x*f;16 }17 18 bool cmp(int a,int b) {return a>b;}19 20 int check(int x) {21     int Alter=0,tot=0;22     for(int i=1;i<=n;++i) {23         if(h[i]<=x) {24             Nw[i]=w[i],Nh[i]=h[i];25             if(h[i]<w[i]) {                26                 if(w[i]>x) continue; 27                 data[++tot]=Nw[i]-Nh[i];28             }29         }30         else {31             if(w[i]>x) return false;32             if(Alter==n/2) return false;33             Alter++,Nw[i]=h[i],Nh[i]=w[i];34         }35     }36     std::sort(data+1,data+1+tot,cmp);37     sum=0;38     tot=n/2-Alter;39     for(int i=1;i<=n;++i) sum+=Nw[i];40     for(int i=1;i<=tot;++i) sum-=data[i];41     return sum;42 }43 44 int hh() {45     freopen("photo.in","r",stdin);46     freopen("photo.out","w",stdout);47     read(n);48     ans=1e9;49     for(int i=1;i<=n;++i) read(w[i]),read(h[i]);50     for(int i=1;i<=1000;++i) {51         int Len=check(i);52         if(Len) ans=ans>i*Len?Len*i:ans;53     }54     printf("%d",ans);55     return 0;56 }57 58 int sb=hh();59 int main(int argc,char**argv) {;}
代码

套路。。 

每次都是2^n 变成 2^(n-1)  这就是线段树从底层向上返回值的变化啊! 

只需要维护一个flag 表示当前层是什么操作 

 1 #include <cstdio> 2 #include <cctype> 3  4 const int MAXN=200010; 5  6 int n,q,k; 7  8 int a[MAXN]; 9 10 struct node {11     int l,r;12     int sum;13 };14 node t[MAXN<<2];15 16 inline void read(int&x) {17     int f=1;register char c=getchar();18     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());19     for(;isdigit(c);x=x*10+c-48,c=getchar());20     x=x*f;21 }22 23 void build_tree(int now,int l,int r,int flag) {24     t[now].l=l;t[now].r=r;25     if(l==r) {26         t[now].sum=a[l];27         return;28     }29     int mid=(l+r)>>1;30     build_tree(now<<1,l,mid,flag^1);31     build_tree(now<<1|1,mid+1,r,flag^1);32     if(flag) t[now].sum=t[now<<1].sum|t[now<<1|1].sum;33     else t[now].sum=t[now<<1].sum^t[now<<1|1].sum;34     return;35 }36 37 void modify(int now,int pos,int v,int flag) {38     if(t[now].l==t[now].r) {39         t[now].sum=v;40         return;41     }42     int mid=(t[now].l+t[now].r)>>1;43     if(pos<=mid) modify(now<<1,pos,v,flag^1);44     else modify(now<<1|1,pos,v,flag^1);45     if(flag) t[now].sum=t[now<<1].sum|t[now<<1|1].sum;46     else t[now].sum=t[now<<1].sum^t[now<<1|1].sum;47     return;48 }49 50 int hh() {51     freopen("xor.in","r",stdin);52     freopen("xor.out","w",stdout);53     read(k);read(q);54     n=1;55     for(int i=1;i<=k;++i) n*=2;56     for(int i=1;i<=n;++i) read(a[i]);57     build_tree(1,1,n,k&1);58     for(int x,y,i=1;i<=q;++i) {59         read(x);read(y);60         modify(1,x,y,k&1);61         printf("%d\n",t[1].sum);62     }63     fclose(stdin);64     fclose(stdout);65     return 0;66 }67 68 int sb=hh();69 int main(int argc,char**argv) {;}
代码

 

原创粉丝点击