省选模拟29
不得不说这题吧有点意思,想半天想不出来,直到要放弃的时候灵光一现!!
第一题,上来干了一个小时,不会,要弃了,后来回头发现就是个dp,我用bfs实现的!
第二题,一路从\(n^3\)到\(n^2\)再到不会了,发现了只有\(\mathcal{O(n)}\)个区间,但是不会快速求值......
第三题,看见期望就跑路了
T1 卷王
直接倒序dp,状态就是亮灭的状态,记录所有的值,输出就好了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1<<17;
const int inf=0x3f3f3f3f;
int T,n;char ch[20];
int val[20][20],all,len;
int dis[N];bool vis[N];
queue<int> q;
signed main(){
freopen("roll.in","r",stdin);
freopen("roll.out","w",stdout);
T=read();
fo(i,0,15){
fo(j,1,i+1)val[i][j]=val[i][j-1]|(1<<i-j+1);
fo(j,i+2,16)val[i][j]=val[i][j-1];
}
memset(dis,0x3f,sizeof(dis));
q.push(0);dis[0]=0;vis[0]=true;
while(!q.empty()){
int x=q.front();q.pop();vis[x]=false;
fo(i,0,15){
int now=x^val[i][dis[x]+1];
if(dis[now]>dis[x]+1){
dis[now]=dis[x]+1;
if(!vis[now])q.push(now),vis[now]=true;
}
fo(j,dis[x]+2,i+1){
now=x^val[i][j];
if(dis[now]>j){
dis[now]=j;
if(!vis[now])q.push(now),vis[now]=true;
}
}
}
}
while(T--){
scanf("%s",ch+1);all=0;len=strlen(ch+1);
fo(i,1,len)all=(all<<1)+(ch[i]^48);
int ret=dis[all];
if(ret==-1)printf("QwQ\n");
else printf("%d\n",ret);
}
return 0;
}
T2 赢王
有贡献的区间一定是在序列上前缀和同余的作为端点
而这样的最小区间的数量事是线性的,直接计算每个区间的答案乘上系数即可,考场上死在了不知道怎么快速计算
快速计算的话,我使用的是主席树
我们发现这个取min操作是从中间分开的,那么我们就可以记录某一个范围内的数的个数和它的和
这样我们分类讨论,毕竟函数值只有两种嘛,好像还挺麻烦的??
AC_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
// #define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1e6+5;
const int mod=998244353;
// const ll inf=0x3f3f3f3f3f3f3f3f;
int n,k,a[N],pre[N];ll ans;
int lsh[N],lh;
struct ZXS{
struct POT{int ls,rs,siz;ll sum;}tr[N*21];
int seg,rt[N];
void pushup(int x){
tr[x].sum=tr[tr[x].ls].sum+tr[tr[x].rs].sum;
tr[x].siz=tr[tr[x].ls].siz+tr[tr[x].rs].siz;
return ;
}
void ins(int &x,int px,int l,int r,int pos,int v){
x=++seg;tr[x]=tr[px];
if(l==r)return tr[x].siz++,tr[x].sum+=v,void();
int mid=l+r>>1;
if(pos<=mid)ins(tr[x].ls,tr[px].ls,l,mid,pos,v);
else ins(tr[x].rs,tr[px].rs,mid+1,r,pos,v);
pushup(x);return ;
}
int sz;ll sm;
void query(int x,int y,int l,int r,int ql,int qr){
if(!x||ql>qr)return ;
if(ql<=l&&r<=qr){
sz+=tr[x].siz-tr[y].siz;
sm+=tr[x].sum-tr[y].sum;
return ;
}
int mid=l+r>>1;
if(ql<=mid)query(tr[x].ls,tr[y].ls,l,mid,ql,qr);
if(qr>mid)query(tr[x].rs,tr[y].rs,mid+1,r,ql,qr);
return ;
}
ll que(int lim,int s,int t,int l,int r,int tp=0){
// cerr<<lim<<" "<<s<<" "<<t<<" "<<l<<" "<<r<<" "<<tp<<endl;
int ql,qr;ll ret=0,res=0;
if(l<lim){sz=sm=0;
ql=lower_bound(lsh+1,lsh+lh+1,l)-lsh;
qr=upper_bound(lsh+1,lsh+lh+1,min(lim-1,r))-lsh-1;
query(rt[t],rt[s-1],1,lh,ql,qr);
ret+=1ll*sz*k+sm-1ll*sz*lim;res+=sz;
}
if(r>lim){sz=sm=0;
ql=lower_bound(lsh+1,lsh+lh+1,max(lim+1,l))-lsh;
qr=upper_bound(lsh+1,lsh+lh+1,r)-lsh-1;
query(rt[t],rt[s-1],1,lh,ql,qr);
ret+=sm-1ll*sz*lim;res+=sz;
}
if(tp)ret=1ll*res*k-ret;
return ret;
}
ll qry(int l,int r){ll ret=0;
// fo(i,l,r)ret+=min((pre[i]-pre[l-1]+k)%k,k-(pre[i]-pre[l-1]+k)%k);
// return ret;
int ql=pre[l-1],qr=(pre[l-1]+(k>>1))%k;
if(ql<=qr)ret+=que(pre[l-1],l,r,ql,qr);
else {
ret+=que(pre[l-1],l,r,ql,k-1);
ret+=que(pre[l-1],l,r,0,qr);
}
ql=(pre[l-1]+(k>>1)+1)%k;qr=(pre[l-1]+k-1)%k;
// cerr<<ql<<" "<<qr<<endl;
if(ql<=qr)ret+=que(pre[l-1],l,r,ql,qr,1);
else {
ret+=que(pre[l-1],l,r,ql,k-1,1);
ret+=que(pre[l-1],l,r,0,qr,1);
}
return ret;
}
}zxs;
int buc[N],nxt[N],fro[N];
bool vis[N];
signed main(){
freopen("win.in","r",stdin);
freopen("win.out","w",stdout);
// cerr<<(sizeof(zxs)>>20)<<endl;
n=read();k=read();
fo(i,1,n){
a[i]=read();
pre[i]=(pre[i-1]+a[i])%k;
lsh[++lh]=pre[i];
}lsh[++lh]=0;
sort(lsh+1,lsh+lh+1);
lh=unique(lsh+1,lsh+lh+1)-lsh-1;
memset(buc,-1,sizeof(buc));
buc[lower_bound(lsh+1,lsh+lh+1,0)-lsh]=0;
fo(i,1,n){
int pos=lower_bound(lsh+1,lsh+lh+1,pre[i])-lsh;
zxs.ins(zxs.rt[i],zxs.rt[i-1],1,lh,pos,pre[i]);
if(~buc[pos])nxt[buc[pos]]=i,fro[i]=buc[pos];
buc[pos]=i;
}
// cerr<<zxs.qry(1,2)<<endl;
ans=(ans-1ll*n*(n+1)/2%mod+mod)%mod;
// cerr<<ans<<endl;
fo(i,0,n)if(!vis[i]){
int now=i,all=1;vis[now]=true;
while(nxt[now])vis[nxt[now]]=true,now=nxt[now],all++;
now=nxt[i];int cnt=0,las=i;
// cerr<<all<<endl;
ans=(ans+1ll*all*(all-1)/2%mod)%mod;
while(now){cnt++;
// cerr<<las<<" "<<now<<" "<<cnt<<" "<<(all-cnt)<<" "<<zxs.qry(las+1,now)<<endl;
ans=(ans+1ll*zxs.qry(las+1,now)%mod*cnt%mod*(all-cnt)%mod)%mod;
las=now;now=nxt[now];
}
}
printf("%lld",ans);
return 0;
}
T3 稳王
最优策略就是攒够了直接上
于是期望就是打不死的回合概率相加+1
于是dp+矩阵,求和公式直接上,dp容斥比较好
好像有好多重复计算...
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();}
return s*t;
}
const int mod=998244353;
int ksm(int x,int y){
int ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;y>>=1;
}return ret;
}
struct matrix{
int x[5][5];
matrix(){memset(x,0,sizeof(x));}
matrix operator * (matrix a)const{
matrix ret;
fo(i,0,4)fo(k,0,4)if(x[i][k])fo(j,0,4)ret.x[i][j]=(ret.x[i][j]+x[i][k]*a.x[k][j])%mod;
return ret;
}
void clear(){memset(x,0,sizeof(x));}
};
matrix mksm(matrix x,int y){
matrix ret;
fo(i,0,4)ret.x[i][i]=1;
while(y){
if(y&1)ret=ret*x;
x=x*x;y>>=1;
}return ret;
}
int sol(int n){
int ret=0,m=(n-1)>>1;
ret=(ret+ksm(2,mod-2))%mod;
ret=(ret+(1-ksm(ksm(3,mod-2),n)+mod)*ksm(2,mod-2))%mod;
// cerr<<ret<<endl;
ret=(ret+(1-ksm(ksm(3,mod-2),m)+mod)*ksm(2,mod-2))%mod;
ret=(ret+(ksm(3,m)-ksm(2,m+1)+1+mod)*ksm(ksm(3,m),mod-2))%mod;
matrix ma,xs;ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][0]=xs.x[1][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][2]=1;
ma=ma*mksm(xs,n+2);
ret=(ret+ma.x[0][2])%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][2]=1;
ma=ma*mksm(xs,n+2);
ret=(ret-ma.x[0][2]+mod)%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[1][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][2]=1;
ma=ma*mksm(xs,n+2);
ret=(ret-ma.x[0][2]+mod)%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][1]=xs.x[1][2]=xs.x[2][2]=1;
ma=ma*mksm(xs,n+2);
ret=(ret+ma.x[0][2])%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][0]=xs.x[2][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][3]=1;
ma=ma*mksm(xs,n+3);
ret=(ret+ma.x[0][3])%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][3]=1;
ma=ma*mksm(xs,n+3);
ret=(ret-ma.x[0][3]+mod)%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[2][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][3]=1;
ma=ma*mksm(xs,n+3);
ret=(ret-ma.x[0][3]+mod)%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][3]=1;
ma=ma*mksm(xs,n+3);
ret=(ret+ma.x[0][3])%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][0]=xs.x[2][0]=xs.x[3][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][4]=xs.x[4][4]=1;
ma=ma*mksm(xs,n+4);
ret=(ret+ma.x[0][4])%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[2][0]=xs.x[3][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][4]=xs.x[4][4]=1;
ma=ma*mksm(xs,n+4);
ret=(ret-ma.x[0][4]+mod)%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][0]=xs.x[3][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][4]=xs.x[4][4]=1;
ma=ma*mksm(xs,n+4);
ret=(ret-ma.x[0][4]+mod)%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][0]=xs.x[2][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][4]=xs.x[4][4]=1;
ma=ma*mksm(xs,n+4);
ret=(ret-ma.x[0][4]+mod)%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[3][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][4]=xs.x[4][4]=1;
ma=ma*mksm(xs,n+4);
ret=(ret+ma.x[0][4])%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[2][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][4]=xs.x[4][4]=1;
ma=ma*mksm(xs,n+4);
ret=(ret+ma.x[0][4])%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][0]=ksm(3,mod-2);
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][4]=xs.x[4][4]=1;
ma=ma*mksm(xs,n+4);
ret=(ret+ma.x[0][4])%mod;
ma.clear();xs.clear();
// cerr<<ret<<endl;
ma.x[0][0]=1;
xs.x[0][1]=xs.x[1][2]=xs.x[2][3]=xs.x[3][4]=xs.x[4][4]=1;
ma=ma*mksm(xs,n+4);
ret=(ret-ma.x[0][4]+mod)%mod;
ma.clear();xs.clear();
return (ret+1)%mod;
}
int T;
signed main(){
freopen("stable.in","r",stdin);
freopen("stable.out","w",stdout);
T=read();
while(T--)printf("%lld\n",sol(read()));
return 0;
}
QQ:2953174821