csp-s模拟测试「9.14」A·B·C(三分,贪心)

博客大概咕了很久了.........

T1 A

大概推下式子就好了,考试时数据点分治DFS前30点T了,然后后70分因为两数相乘爆long long然后本来可以A掉,就WA零了.......

式子推出来肯定能化成S*B^n+A*B^x+A*B^y.........

我们可以看出划出这样的式子,那么首先肯定要乘n次,即S乘的B的系数,然后加的操作就是剩下式子的系数和

当然n是大于x,y.....因为S是肯定要被乘最多次的

然后在求系数时考虑求lca的那种打法

如果确定T-S*B^n可以整除A那么肯定能拆分成若干个这样的数相加的形式

所以直接求即可

注意乘爆long long

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 #define MAXN 100000100
 4 using namespace std;
 5 int S,T,A,B;int ans=0;int TT;
 6 int b[MAXN];int minn=0x7ffffffff;
 7 int min1(int x,int y){
 8     if((double)x>(double)y)return y;
 9     return x;
10 }
11 void work1(){
12      b[0]=A;
13      int ptt=1;TT=T;
14      while(1){           
15            if((b[ptt-1]/A)>(T/B)+1)break;
16            b[ptt]=b[ptt-1]*B;
17            ptt++;
18      }
19      ptt--;
20      int me=0;int ok=0;
21      for(int i=ptt;i>=0;--i){
22          me=b[i]/A;
23          ans=0;
24          T=TT;
25          if(S<=(T/me+1)&&(T-S*me)%A==0){
26             ok=i;ans=i;T-=S*me;
27             for(int j=ok;j>=0;--j){
28                 if(T>=b[j]){
29                    ans=ans+T/b[j];
30                    T-=T/b[j]*b[j];
31                  }
32             }
33             minn=min1(minn,ans);
34             break;
35          }
36      }
37      printf("%lld
",minn);
38 } 
39 signed main(){
40      scanf("%lld%lld%lld%lld",&S,&T,&A,&B);
41      work1();
42 }
View Code

T2 B

不会,咕了

T3 C

首先对于p<=30的数据我们可以直接循环需要多少个特殊加热器

然后贪心处理最少花费

贪心的话,对于当前位置,只要找到能覆盖其的最大范围将其覆盖上,当然也有可能无法覆盖,就只能用

特殊用电器,至于区间修改,线段树即可。

然后可以考虑三分

对于当前1-n的区间来说,我们在一开始用超级用电器,可能会使使用正常用电器的费用减少

但是随着超级用电器的使用次数增加,会有一些节点已经达到所要P值

所以,费用减少的速度越来越少

那么我们就可以发(da)现(biao)这是个三分函数,直接三分即可

  1 #include<bits/stdc++.h>
  2 #define MAXN 110000
  3 #define int long long
  4 using namespace std;
  5 int read(){
  6     int x=0;char c=getchar();
  7     while(c<'0'||c>'9')c=getchar();
  8     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
  9     return x;
 10 }
 11 struct node{int l,r,p,f;}t[4*MAXN];int n,m,T;
 12 struct no{int l,r;}e[MAXN];int p[MAXN];
 13 int v[MAXN][2];
 14 void build(int k,int l,int r){
 15      t[k].l=l;t[k].r=r;t[k].f=0;
 16      if(l==r){t[k].p=p[l];return ;}
 17      int mid=(l+r)>>1;
 18      build(k*2,l,mid);
 19      build(k*2+1,mid+1,r);
 20 }
 21 void down(int k){
 22      t[k*2].f+=t[k].f;t[k*2+1].f+=t[k].f;
 23      t[k*2].p+=t[k].f;t[k*2+1].p+=t[k].f;
 24      t[k].f=0;
 25 }
 26 void add(int k,int l,int r,int x){
 27      if(l<=t[k].l&&r>=t[k].r){
 28         t[k].p+=x;t[k].f+=x;
 29         return ;
 30      }
 31      if(t[k].f)down(k);
 32      int mid=(t[k].l+t[k].r)>>1;
 33      if(l<=mid)add(k*2,l,r,x);
 34      if(r>mid)add(k*2+1,l,r,x);
 35 }
 36 int ask(int k,int x){
 37      if(t[k].l==t[k].r)return t[k].p;
 38      int mid=(t[k].l+t[k].r)>>1;
 39      if(t[k].f)down(k);
 40      if(x<=mid)return ask(k*2,x);
 41      else return ask(k*2+1,x);
 42 }
 43 int minn=0x7fffffffff;int ans=0;int maxn_id=0,maxn_r=0;
 44 int work(int wb){
 45      ans=0;
 46      maxn_id=0;maxn_r=0;
 47      build(1,1,n);
 48      add(1,1,n,-wb);
 49      ans=ans+T*wb;
 50      for(int i=1;i<=n;++i){
 51          int id=v[i][1];
 52          if(e[id].r>maxn_r){
 53              maxn_r=e[id].r;maxn_id=id;
 54          }
 55          int me=ask(1,i);
 56          if(maxn_r<i&&me>0){
 57               ans+=T*me;add(1,1,n,-me);
 58          }
 59          else if(me>0){
 60               ans+=me;
 61               add(1,e[maxn_id].l,e[maxn_id].r,-me);
 62          }
 63      }
 64      minn=min(ans,minn);
 65      return ans;
 66 }
 67 int ma=0;
 68 void third_divide(){
 69      int l=0;int r=ma;
 70      while(l+2<r){
 71            int mid=l+(r-l)/3;
 72            int midd=r-(r-l)/3;
 73            if(work(mid)>work(midd)){l=mid;}
 74            else r=midd;
 75      }
 76      minn=min(minn,work(l));
 77      minn=min(minn,work(l+1));
 78      minn=min(minn,work(r));
 79      printf("%lld
",minn);
 80 }
 81 signed main(){
 82      n=read();m=read();T=read();
 83      for(int i=1;i<=n;++i){
 84          p[i]=read();ma=max(ma,p[i]);
 85      }
 86      for(int i=1;i<=m;++i){
 87          e[i].l=read();e[i].r=read();
 88          if(e[i].r>v[e[i].l][0]){
 89             v[e[i].l][0]=e[i].r;
 90             v[e[i].l][1]=i;
 91          }
 92      }    
 93      third_divide();
 94 }
 95 /*#include<bits/stdc++.h>
 96 #define int long long
 97 using namespace std;
 98 int random(int x){return rand()%x;}
 99 int gcdd(int x,int y){
100     return (y==0)?x:gcdd(y,x%y);
101 }
102 signed main(){       
103        freopen("text.in","w",stdout);
104        srand((unsigned)time(0));
105        int n=4;int m=4;int T=10000;
106        printf("%lld %lld %lld
",n,m,T);
107        for(int i=1;i<=n;++i){
108            printf("%lld ",random(4)+1);
109        }
110        cout<<endl;
111        for(int i=1;i<=m;++i){
112            int r=random(n)+1;
113            printf("%lld %lld
",random(r)+1,r);
114        }
115 }
116 */
View Code
原文地址:https://www.cnblogs.com/Wwb123/p/11524297.html