zoukankan      html  css  js  c++  java
  • 9.14题解

    T1

    对于这个数据范围,我们发现我们不断的乘$b$,什么都不加,$b$是最小的2,$T$是最小的1,最多也就乘大概60次就足够了,也就是说我们完全可以枚举乘过几个$b$,既然我们确定了需要乘几个$b$,那加$a$也就可以确定了,我们可以得到$m{ imes}a=T-S{ imes}b^x$,我们就可以得到m的值,而关键就是求出$b$进制下的m,这样的话我们就可以直接统计加了几次$a$了,显然是个进制转化,照着二进制乱搞就可以了

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define maxx 1001000
     5 #define ll long long
     6 #define inf 2000000000000000000
     7 using namespace std;
     8 ll S,T,a,b,base=1,m,ans=inf;
     9 ll ksm(ll a,int b)
    10 {
    11     ll ans=1;
    12     while(b)
    13     {
    14         if(b&1)  ans*=a;
    15         b=b>>1;  a*=a;
    16     }
    17     return ans;
    18 }
    19 int main()
    20 {
    21     scanf("%lld%lld%lld%lld",&S,&T,&a,&b);
    22     for(int i=0;i<=64;++i)
    23     {
    24         if(base>T/S)  break;
    25         ll cha=T-S*base;
    26         if(cha%a==0)  m=cha/a;
    27         else  {base*=b;  continue;}
    28         ll sum=i;
    29         for(int j=i;j>=0;--j)
    30         {
    31             ll mi=ksm(b,j);
    32             sum+=m/mi;  m%=mi;
    33         }
    34         base*=b;  ans=min(ans,sum);
    35     }
    36     printf("%lld
    ",ans);
    37     return 0;
    38 }
    View Code

    T2

    不知道为什么我像失忆了一般,我明明记得我打完了这道题,然而我残存的代码告诉我,我刚开始码他。。。。咕了

    T3

    他们发现了费用随特殊加热器的使用次数呈单谷函数,我们就可以愉快的开启三分的旅程,怎么$check$呢?考虑贪心,由于我们每次用普通加热器都会覆盖一段区间,所以用树状数组进行差分,首先预处理出来我如果在当前这个点使用普通加热器,最多能覆盖到哪一个点,$check$的时候从第一个点开始,如果还没有达到希望的能量,就使用加热器使他达到,顺带使可以和他一起使用加热器的点需要的能量值变少即可

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<bits/stdc++.h>
     6 #define maxn 100100
     7 #define int long long
     8 using namespace std;
     9 struct node{
    10     int l,r;
    11 }a[maxn];
    12 int n,m,t,co_ba,maxx,l=0,r,head=1,minn=0x7fffffffffffffff;
    13 int p[maxn],flag[maxn],c[maxn],to[maxn],sf[maxn];
    14 bool cmp(const node &a,const node &b)
    15 {
    16     return a.l<b.l;
    17 }
    18 int lowbit(int x)
    19 {
    20     return x&(-x);
    21 }
    22 void add(int pos,int w)
    23 {
    24     for(;pos<=n;pos+=lowbit(pos))  c[pos]+=w;
    25 }
    26 int query(int pos)
    27 {
    28     int ans=0;
    29     for(;pos>0;pos-=lowbit(pos))  ans+=c[pos];
    30     return ans;
    31 }
    32 int check(int x)
    33 {
    34     memset(c,0,sizeof(c));
    35     int sum=x*t;
    36     for(int i=1;i<=n;++i)  sf[i]=max(1ll*0,p[i]-x);
    37     for(int i=1;i<=n;++i)  add(i,sf[i]-sf[i-1]);
    38     for(int i=1;i<=n;++i)
    39     {
    40         int ww=query(i);
    41         if(ww<=0)  continue;
    42         sum+=ww;  add(i,-ww);  add(to[i]+1,ww);
    43     }
    44     return sum;
    45 }
    46 signed main()
    47 {
    48     scanf("%lld%lld%lld",&n,&m,&t);
    49     for(int i=1;i<=n;++i)  scanf("%lld",&p[i]);
    50     for(int i=1;i<=m;++i)
    51     {
    52         scanf("%lld%lld",&a[i].l,&a[i].r);
    53         for(int j=a[i].l;j<=a[i].r;++j)  flag[j]=1;
    54     }
    55     sort(a+1,a+m+1,cmp);
    56     for(int i=1;i<=n;++i)
    57         if(!flag[i])  maxx=max(maxx,p[i]);
    58     for(int i=1;i<=n;++i)  {p[i]=max(1ll*0,p[i]-maxx);  r=max(r,p[i]);}
    59     co_ba=t*maxx;  maxx=0;
    60     for(int i=1;i<=n;++i)
    61     {
    62         while(a[head].l<=i&&head<=m)  {maxx=max(maxx,a[head].r);  head++;}
    63         to[i]=maxx;
    64     }
    65     while(l+1<r)
    66     {
    67         int mid=(l+r)>>1;
    68         int cost1=check(mid-1),cost2=check(mid);
    69         minn=min(minn,cost1);  minn=min(minn,cost2);
    70         if(cost1>=cost2)  l=mid;
    71         else  r=mid;
    72     }
    73     co_ba+=minn;  printf("%lld
    ",co_ba);
    74     return 0;
    75 }
    View Code

    T4

    说一下思路过程吧,一开始打了个暴力,枚举连接的两个端点直接求花费,然后只有30分,后来打了个小表发现一个端点确定之后另一个端点可以三分,就有了$T60$的好成绩,然后我就突然发现两个端点似乎可以三分套三分,但是由于中间平的地方太多,单谷不严格,所以三分本来就是死的,三分套三分就死透了,然后我惊讶的得知这道题数据水到随机化可$A$,然后我就$A$了。。。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #define maxn 100010
     4 using namespace std;
     5 struct node{
     6     int l,r;
     7 }q[maxn];
     8 int n,m,head,tail,ans=0x7fffffff;
     9 int check()
    10 {
    11     int maxx=0;
    12     for(int i=1;i<=m;++i)
    13     {
    14         int len=q[i].r-q[i].l;
    15         if(head>q[i].l&&tail<q[i].r)  len=min(len,head-q[i].l+q[i].r-tail);
    16         else if(head<=q[i].l&&tail>=q[i].r)  len=min(q[i].r-q[i].l,q[i].l-head+tail-q[i].r);
    17         else if(head>q[i].l&&tail>=q[i].r)  len=min(q[i].r-q[i].l,head-q[i].l+tail-q[i].r);
    18         else if(head<=q[i].l&&tail<q[i].r)  len=min(q[i].r-q[i].l,q[i].l-head+q[i].r-tail);
    19         maxx=max(maxx,len);
    20         if(maxx>=ans)  return maxx;
    21     }
    22     return maxx;
    23 }
    24 int main()
    25 {
    26     scanf("%d%d",&n,&m);
    27     for(int i=1;i<=m;++i)  scanf("%d%d",&q[i].l,&q[i].r);
    28     if(m==1)  {printf("0
    ");  return 0;}
    29     for(int i=1;i<=n;++i)
    30     {
    31         int l=i+2,r=n;
    32         while(l+1<r)
    33         {
    34             int mid=(l+r)>>1;
    35             head=i;  tail=mid-1;
    36             int cost1=check();
    37             head=i;  tail=mid;
    38             int cost2=check();
    39             ans=min(ans,cost1);  ans=min(ans,cost2);
    40             if(cost1>=cost2)  l=mid;
    41             else  r=mid;
    42         }
    43     }
    44     printf("%d
    ",ans);
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    人生苦短之我用Python篇(遍历、函数、类)
    Python基础篇
    OSPF 配置
    RIPng 知识要点
    RIP 知识要点
    Cisco DHCP 配置要点
    python读取mat文件
    theano提示:g++ not detected的解决办法
    Can Microsoft’s exFAT file system bridge the gap between OSes?
    matlab 大块注释和取消注释的快捷键
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11626675.html
Copyright © 2011-2022 走看看