zoukankan      html  css  js  c++  java
  • Codeforces Round #538 (Div. 2)

    A.Got Any Grapes?

    根据题意模拟就好。

    B.Yet Another Array Partitioning Task

    题意:

    给出一个大小为n的数组,把它分成k段,每一段最大的m个数字加起来和最大。

    题解:

    那么最好的答案就是这n个数里面最大的m*k个数都被取到。

    C.Trailing Loves (or L'oeufs?)

    题意

    求n!在b进制下末尾的0的个数。其中n<=1e18,b<=1e12

    题解:

    模拟一下进制转换的过程我们发现,等价于求n!mod b^k=0的k的最大值。我们如果把n!和b都进行质因子分解,对于质数p,n!对于p的指数是b1,对于b的指数是b2,那么当b2不为0的时候,k=min(b1/b2).但是n!非常大,连求出来都不可能。那么我们可以把b因数分解,然后对于b的每一质因数,求出n!中这个质因数的质数。然后问题就只剩对于质数p,怎么求n!中p的指数。我们都知道n/p是求1-n中能被p整除的数的个数,就用这种方法求就好。注意容易爆longlong

    我一开始那一段是这么写的然后一直wa

    1 LL cal(LL n,LL p){//n!中质数p的指数
    2     LL res=0;
    3     LL num=p;
    4     while(n/num>=1){
    5         res+=n/num;
    6         num=num*p;
    7     }
    8     return res;
    9 }
    View Code

    然后加了个break就a了。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cmath>
     6 
     7 using namespace std;
     8 const long long INF=1e18;
     9 const int maxn=100000;
    10 typedef long long LL;
    11 LL n,b;
    12 LL prime[maxn];
    13 int cnt,num[maxn];
    14 void solve(LL x){
    15     int m=sqrt(x);
    16     for(int i=2;i<=m;i++){
    17         if(x%i==0){
    18             cnt++;
    19             prime[cnt]=i;
    20             while(x%i==0){
    21                 num[cnt]++;
    22                 x/=i;
    23             }
    24         }
    25     }
    26     if(x>1){
    27         cnt++;
    28         prime[cnt]=x;
    29         num[cnt]++;
    30     }
    31 }
    32 
    33 LL cal(LL n,LL p){//n!中质数p的指数
    34     LL res=0;
    35     LL num=p;
    36     while(n/num>=1){
    37         res+=n/num;
    38         if(num>n/p)break;
    39         num=num*p;
    40     }
    41     return res;
    42 }
    43 
    44 int main(){
    45     scanf("%I64d%I64d",&n,&b);
    46     solve(b);
    47     LL ans=INF;
    48     //LL c=cal(n,prime[1]);
    49 
    50     for(int i=1;i<=cnt;i++){
    51         ans=min(ans,cal(n,prime[i])/num[i]);
    52     }
    53     printf("%I64d
    ",ans);
    54 return 0;
    55 }
    View Code

     D.Flood Fill

    这个就是个入门的区间dp,记忆话很好写。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 const int maxn=5000+10;
     8 const int INF=2147000000;
     9 int n;
    10 int c[maxn];
    11 int f[maxn][maxn];
    12 int L[maxn],R[maxn];
    13 int dp(int l,int r){
    14     if(f[l][r])
    15         return f[l][r];
    16     if(l==1&&r==n)
    17         return 0;
    18     f[l][r]=INF;
    19     if(c[l-1]==c[r+1]){
    20         f[l][r]=min(f[l][r],dp(L[l-1],R[r+1])+1);
    21     }else{
    22         if(l>1)f[l][r]=min(f[l][r],dp(L[l-1],r)+1);
    23         if(r<n)f[l][r]=min(f[l][r],dp(l,R[r+1])+1);
    24     }
    25     return f[l][r];
    26 }
    27 int main(){
    28     scanf("%d",&n);
    29     for(int i=1;i<=n;i++){
    30         scanf("%d",&c[i]);
    31         if(c[i]==c[i-1])
    32             L[i]=L[i-1];
    33         else L[i]=i;
    34     }
    35     for(int i=n;i>=1;i--){
    36         if(c[i]==c[i+1])
    37             R[i]=R[i+1];
    38         else R[i]=i;
    39     }
    40 //    for(int i=1;i<=n;i++){
    41 //        printf("%d %d %d
    ",i,L[i],R[i]);
    42 //    }
    43     int ans=INF;
    44     for(int i=1;i<=n;i++){
    45         ans=min(ans,dp(L[i],R[i]));
    46     }
    47     printf("%d
    ",ans);
    48 return 0;
    49 }
    View Code

    E.Arithmetic Progression(交互题)

    题意:

    存在一个打乱顺序的n个数的等差数列。你要通过最多60次询问,得到这个等差数列的d和a1,也就是公差和最小的值。
    询问有两种
    1. ? i,询问第i个元素是什么
    2. > x,询问是否存在严格大于x的值
    题解:
    如果这个题是找最大值的话就很容易了,二分就可以了,最小值呢就用最大值减去n-1的公差就好了。问题是怎么求公差d呢?对于打乱顺序的a,|ai-ai-1|=di,那么di一定是公差d的倍数。那么我们随机拿出30个数来,排序然后求di,然后求这些di的gcd,得到的就是公差d。我不太会证明,只能靠猜···
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    
    using namespace std;
    const int maxn=1e6+100;
    
    int gcd(int a,int b){
        if(!b)return a;
        return gcd(b,a%b);
    }
    int ask1(int x){
        printf("? %d
    ",x);
        fflush(stdout);
        int res;
        scanf("%d",&res);
        return res;
    }
    int ask2(int x){
        printf("> %d
    ",x);
        fflush(stdout);
        int res;
        scanf("%d",&res);
        return res;
    }
    
    int n,m;
    int a[maxn];
    int main(){
        srand(time(NULL));
        scanf("%d",&n);
        for(int i=1;i<=30;i++){
            int r=rand()*rand()%n+1;
            int x=ask1(r);
            a[++m]=x;
        }
        sort(a+1,a+1+m);
        int d=a[2]-a[1];
        for(int i=3;i<=m;i++)
            d=gcd(d,a[i]-a[i-1]);
        int l=0,r=1e9,ans=0;
        while(l<=r){
            int mid=l+(r-l)/2;
            if(ask2(mid)){
                l=mid+1;
            }else{
                ans=mid;
                r=mid-1;
            }
        }
        printf("! %d %d
    ",ans-(n-1)*d,d);
    return 0;
    }
    View Code

    F:Please, another Queries on Array?

    题意:给出一个n个数字的数组,和q个询问。

    询问有两种
    1."MULTIPLY l r x"
    将[l,r]的m每个数都乘x
    2."TOTIENT l r"
    输出phi(al*al+1*...*ar)mod 1e9+7

    题解:

    我们要先回想一下欧拉函数的性质。

    然后对于这个题

    300以内只有62个,可以状态压缩,显然也可以用线段树维护。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <cmath>
      6 
      7 using namespace std;
      8 typedef long long LL;
      9 const int maxn=4e5+10;
     10 const int mod=1e9+7;
     11 
     12 int n,q,sz;
     13 int a[maxn],prime[100],vis[400],pos[400];
     14 
     15 void init(){
     16     int m=sqrt(300);
     17     for(int i=2;i<=m;i++){
     18         if(!vis[i]){
     19             for(int j=i*i;j<=300;j+=i){
     20                 vis[j]=1;
     21             }
     22         }
     23     }
     24     for(int i=2;i<=300;i++){
     25         if(!vis[i]){
     26             prime[sz]=i;
     27             pos[i]=sz++;
     28         }
     29     }
     30 }
     31 LL qpow(int n,int k){
     32     LL res=1;
     33     while(k){
     34         if(k&1)res=res*n%mod;
     35         n=(LL)n*n%mod;
     36         k>>=1;
     37     }
     38     return res%mod;
     39 }
     40 LL mulv[4*maxn],prmv[4*maxn];
     41 LL tag_m[4*maxn],tag_p[4*maxn];
     42 LL solve(int x){
     43     LL res=0;
     44     int m=sqrt(x);
     45     for(int i=2;i<=m;i++){
     46         if(x%i==0){
     47             res|=(LL)(1ll<<pos[i]);
     48             while(x%i==0)
     49                 x/=i;
     50         }
     51     }
     52     if(x>1){
     53         res|=(LL)(1ll<<pos[x]);
     54     }
     55     return res;
     56 }
     57 
     58 void maintain(int o){
     59     int lc=2*o,rc=2*o+1;
     60     mulv[o]=mulv[lc]*mulv[rc]%mod;
     61     prmv[o]=prmv[lc]|prmv[rc];
     62 }
     63 
     64 void pushdown(int o,int L,int R){
     65     int lc=2*o,rc=2*o+1;
     66     if(tag_m[o]!=1){
     67         int M=L+(R-L)/2;
     68 
     69         mulv[lc]=qpow(tag_m[o],M-L+1)*mulv[lc]%mod;
     70         mulv[rc]=qpow(tag_m[o],R-M)*mulv[rc]%mod;
     71         tag_m[lc]=tag_m[o]*tag_m[lc]%mod;
     72         tag_m[rc]=tag_m[o]*tag_m[rc]%mod;
     73         tag_m[o]=1;
     74     }
     75     if(tag_p[o]){
     76         prmv[lc]|=tag_p[o];
     77         prmv[rc]|=tag_p[o];
     78         tag_p[lc]|=tag_p[o];
     79         tag_p[rc]|=tag_p[o];
     80         tag_p[o]=0;
     81     }
     82 }
     83 
     84 void build(int o,int L,int R){
     85     mulv[o]=tag_m[o]=1;
     86     prmv[o]=tag_p[o]=0;
     87     if(L==R){
     88         mulv[o]=a[L];
     89         prmv[o]=solve(a[L]);
     90         return ;
     91     }
     92     int M=L+(R-L)/2;
     93     build(2*o,L,M);
     94     build(2*o+1,M+1,R);
     95     maintain(o);
     96 }
     97 void update(int o,int L,int R,int ql,int qr,int v){
     98     if(ql<=L&&qr>=R){
     99         mulv[o]=mulv[o]*qpow(v,R-L+1)%mod;
    100         tag_m[o]=tag_m[o]*v%mod;
    101         LL S=solve(v);
    102         tag_p[o]|=S;
    103         prmv[o]|=S;
    104         return;
    105     }
    106     int M=L+(R-L)/2;
    107     pushdown(o,L,R);
    108     if(ql<=M)update(2*o,L,M,ql,qr,v);
    109     if(qr>M)update(2*o+1,M+1,R,ql,qr,v);
    110     maintain(o);
    111 }
    112 LL ans_S,ans;
    113 void query(int o,int L,int R,int ql,int qr){
    114     if(ql<=L&&qr>=R){
    115         ans=ans*mulv[o]%mod;
    116         ans_S|=prmv[o];
    117         return;
    118     }
    119     int M=L+(R-L)/2;
    120     pushdown(o,L,R);
    121 
    122     if(ql<=M)query(2*o,L,M,ql,qr);
    123     if(qr>M)query(2*o+1,M+1,R,ql,qr);
    124     maintain(o);
    125 }
    126 void gcd(LL a,LL b,LL& d,LL& x,LL& y){
    127     if(!b){
    128         d=a;x=1;y=0;
    129     }else{
    130         gcd(b,a%b,d,y,x);
    131         y-=x*(a/b);
    132     }
    133 }
    134 LL inv(LL a,LL p){
    135     LL d,x,y;
    136     gcd(a,p,d,x,y);
    137     if(d!=1)return -1;
    138     return (x+p)%p;
    139 }
    140 void tra(int o,int L,int R){
    141     printf("%d %d %d %I64d %I64d
    ",o,L,R,mulv[o],prmv[o]);
    142     if(L==R)return;
    143     int M=L+(R-L)/2;
    144     tra(2*o,L,M);
    145     tra(2*o+1,M+1,R);
    146 }
    147 
    148 int main(){
    149     init();
    150     scanf("%d%d",&n,&q);
    151     for(int i=1;i<=n;i++){
    152         scanf("%d",&a[i]);
    153     }
    154     build(1,1,n);
    155    // tra(1,1,n);
    156     for(int i=1;i<=q;i++){
    157         string type;
    158         cin>>type;
    159         if(type=="TOTIENT"){
    160             int ql,qr;
    161             scanf("%d%d",&ql,&qr);
    162             ans=1,ans_S=0;
    163             query(1,1,n,ql,qr);
    164             LL sum=1;
    165             for(int j=0;j<62;j++){
    166                 LL S=(LL)(1ll<<j);
    167                 if(ans_S&S){
    168                     sum=sum*(prime[j]-1)%mod*inv(prime[j],mod)%mod;
    169                    // printf("@%d %I64d %I64d
    ",prime[j],inv(prime[j],mod),inv(prime[j],mod)*prime[j]%mod);
    170                 }
    171             }
    172             LL ANS=sum*ans%mod;
    173             printf("%I64d
    ",ANS);
    174         }else{
    175             int ql,qr,v;
    176             scanf("%d%d%d",&ql,&qr,&v);
    177             update(1,1,n,ql,qr,v);
    178         }
    179     }
    180 return 0;
    181 }
    View Code
  • 相关阅读:
    xml
    企业级应用和互联网应用的区别
    javaee学习目标
    数据库基本原理
    数据库学习感想
    数据库设计
    团队项目自我评价
    团队项目-软件度量
    团队项目-初级版本
    团队项目—详细设计
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/10384033.html
Copyright © 2011-2022 走看看