码迷,mamicode.com
首页 > 其他好文 > 详细

20190915杂题选讲

时间:2019-09-20 22:51:23      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:efi   turn   str   clu   can   printf   lse   shu   杂题   

T1

\(b_1=p_1^{a_1}p_2^{a_2}…p_n^{a_n}\),显然答案最大为\(\sum a_i\)

考虑让\(\sum a_i\)最大,那\(b_1\)不能有有超过5的质因子,因为\(2^2<5\)。3的个数最多也只有一个,因为\(2^3<3^2\)

于是就可以dp,设\(f[i][j][k]\)表示填到第i个数,gcd可以表示为\(2^j3^k\)的答案,分类讨论转移一下,最后答案为\(f[n][0][0]\)

code:

#include <bits/stdc++.h>
#define N 1000005
#define ll long long
#define il inline 
#define For(i,x,y) for(int i=(x);i<=(y);++i) 
#define Rof(i,x,y) for(int i=(x);i>=(y);--i)
#define mod 1000000007
using namespace std;
int f[N][20][2],n,_2[N],_3[N],lim2;

int main(){
    int n;
    scanf("%d",&n);_2[0]=1;
    int x=log2(n);
    For(i,1,x) _2[i]=_2[i-1]*2%mod;
    for(int bit=0,i=1;i<=n;i*=3,bit++) _3[bit]=i;
    f[1][x][0]=1;
    if((1<<(x-1))*3<=n) f[1][x-1][1]=1;
    For(i,2,n)
        Rof(j,x,0){
            Rof(k,(n>=3),0){
                if(_2[j]*_3[k]<=n){
                    (f[i][j][k]+=1ll*f[i-1][j][k]*max(0ll,1ll*n/(_2[j]*_3[k])-i+1)%mod)%=mod;
                    if(j>0) (f[i][j-1][k]+=1ll*f[i-1][j][k]*(1ll*n/(_2[j-1]*_3[k])-n/(_2[j]*_3[k]))%mod)%=mod;
                    if(k>0) (f[i][j][k-1]+=1ll*f[i-1][j][k]*(1ll*n/(_2[j]*_3[k-1])-n/(_2[j]*_3[k]))%mod)%=mod;                  
                }
            }               
        }
    printf("%d\n",f[n][0][0]);
}

T2

先贴个代码,回家补题解

#include <bits/stdc++.h>
#define N 200005
#define ll long long
#define il inline 
#define For(i,x,y) for(int i=(x);i<=(y);++i) 
#define Rof(i,x,y) for(int i=(x);i>=(y);--i)
#define mid ((l+r)>>1)
#define lson t[o].ls,l,mid
#define rson t[o].rs,mid+1,r
#define bas rt,1,n
#define mod 998244353
using namespace std;

int cnt=0,rt=1,_=0;
ll _pow[N];
struct qwq{ int ls,rs;ll f,g,tf,tg,ans; } t[N<<2];

il void add(ll &x,ll y){ x+y>=mod?x=x+y-mod:x=x+y; }
il ll adD(ll x,ll y){ return x+y>=mod?x+y-mod:x+y; }
il ll mnS(ll x,ll y){ return x-y<0?x-y+mod:x-y; }
il void pushup(int o){ t[o].ans=adD(adD(t[t[o].ls].ans,t[t[o].rs].ans),t[o].f); }
void build(int &o,int l,int r){
    o=++cnt;
    t[o].f=t[o].ans=0;
    t[o].g=t[o].tf=t[o].tg=1;
    if(l==r) return;
    build(lson),build(rson);
    pushup(o);
}
il void pushdowntg(int o,int x){
    t[o].g=1ll*t[o].g*x%mod;
    t[o].tg=1ll*t[o].tg*x%mod;
}
il void pushdowntf(int o,int x){
    t[o].f=1ll*t[o].f*x%mod;
    t[o].tf=1ll*t[o].tf*x%mod;
    t[o].ans=1ll*t[o].ans*x%mod;    
}
il void PushDown(int o){
    if(t[o].tf!=1) pushdowntf(t[o].ls,t[o].tf),pushdowntf(t[o].rs,t[o].tf),t[o].tf=1;
    if(t[o].tg!=1) pushdowntg(t[o].ls,t[o].tg),pushdowntg(t[o].rs,t[o].tg),t[o].tg=1;
}
void modify(int o,int l,int r,int L,int R){
    PushDown(o);
    int _l=t[o].ls,_r=t[o].rs;
    if(L==l && r==R){
        add(t[o].f,_pow[_]);
        pushdowntf(_l,2),pushdowntf(_r,2);
        pushup(o);
        return;
    }
    add(t[o].g,_pow[_]);
    if(R<=mid){
        modify(lson,L,R);
        PushDown(_r);
        add(t[_r].f,mnS(_pow[_],t[_r].g)),add(t[_r].g,t[_r].g);
        pushdowntf(t[_r].ls,2),pushdowntf(t[_r].rs,2);
        pushdowntg(t[_r].ls,2),pushdowntg(t[_r].rs,2);
        pushup(_r);
    } else if(L>mid){
        modify(rson,L,R);       
        PushDown(_l);
        add(t[_l].f,mnS(_pow[_],t[_l].g)),add(t[_l].g,t[_l].g);
        pushdowntf(t[_l].ls,2),pushdowntf(t[_l].rs,2);
        pushdowntg(t[_l].ls,2),pushdowntg(t[_l].rs,2);
        pushup(_l);
    } else modify(lson,L,mid),modify(rson,mid+1,R);
    pushup(o);
}

int main(){
    int n,q,op,l,r;_pow[0]=1;
    scanf("%d%d",&n,&q);
    For(i,1,q) _pow[i]=(_pow[i-1]+_pow[i-1])%mod;
    build(bas);
    while(q--){
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d",&l,&r);
            modify(bas,l,r);
            _++;
        } else printf("%lld\n",t[rt].ans);
    }
} 

T3

\(l=l-1\), \(L=\lfloor l/m \rfloor\), \(R=\lfloor r/m \rfloor\)

最后的式子可以化成\((pre[r]-k*R)-(pre[l]-k*L)-k*\lceil (r\%m-l\%m)/m \rceil\)

获得i对应的左端点时,处理一下i前出现的每个余数对应的最小值就行了

code:

#include <bits/stdc++.h>
#define N 1000005
#define ll long long
#define il inline 
#define For(i,x,y) for(int i=(x);i<=(y);++i) 
#define Rof(i,x,y) for(int i=(x);i>=(y);--i)
#define Edge(x) for(int i=head[x];i;i=e[i].nxt)
#define mod 1000000007
#define lson l,mid,o<<1
#define rson mid+1,r,o<<1|1
#define ls(x) t[x].ls,l,mid
#define rs(x) t[x].rs,mid+1,r
#define mset(x,y) memset(x,y,sizeof(x))
#define mcpy(x,y) memcpy(x,y,sizeof(x))
using namespace std;
 
ll pre[N],mn[11];
 
int main(){
    int n,m,k;
    ll ans=0;
    scanf("%d%d%d",&n,&m,&k);
    mset(mn,0x3f);mn[0]=0;
    For(i,1,n) scanf("%lld",&pre[i]),pre[i]+=pre[i-1];
    For(i,1,n) pre[i]-=1ll*k*(1ll*i/m);
    For(i,1,n){
        For(j,0,min(i-1,m-1))
            ans=max(pre[i]-mn[j]-k*((i%m-j+m-1)/m),ans);
        mn[i%m]=min(mn[i%m],pre[i]);
    }
    printf("%lld\n",ans);
} 

T4

题解咕了,放个代码:

#include <bits/stdc++.h>
#define N 5000005
#define ll long long
#define il inline 
#define For(i,x,y) for(int i=(x);i<=(y);++i) 
#define Rof(i,x,y) for(int i=(x);i>=(y);--i)
#define Edge(x) for(int i=head[x];i;i=e[i].nxt)
#define mod 19260817
#define lson l,mid,o<<1
#define rson mid+1,r,o<<1|1
#define ls(x) t[x].ls,l,mid
#define rs(x) t[x].rs,mid+1,r
#define mset(x,y) memset(x,y,sizeof(x))
#define mcpy(x,y) memcpy(x,y,sizeof(x))
using namespace std;
char s[N],t[N];
ll f[30],ans=1;
int main(){
    int n,m,cnt=0;
    scanf("%d%d\n%s\n%s",&n,&m,s+1,t+1);
    cnt=n;
    For(i,1,m){
        if(t[i]>='A' && t[i]<='Z'){
            ll tmp=f[t[i]-'A'];
            f[t[i]-'A']=ans;
            ans=(2ll*ans%mod-tmp+mod)%mod;
        } else{
            if(!cnt) continue;
            (ans+=1)%=mod;
            (f[s[cnt]-'A']+=1)%=mod;
            cnt--;
        }
    } printf("%lld\n",ans);
}

20190915杂题选讲

标签:efi   turn   str   clu   can   printf   lse   shu   杂题   

原文地址:https://www.cnblogs.com/PsychicBoom/p/11560138.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!