20190915杂题选讲
Posted psychicboom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20190915杂题选讲相关的知识,希望对你有一定的参考价值。
T1
设\(b_1=p_1^a_1p_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杂题选讲的主要内容,如果未能解决你的问题,请参考以下文章