省选模拟41
今天好像是和石二要排大榜的,于是我再次考炸了
开场是先看T1的,想要切掉,但是不断转换做法,很容易弄成重点,容斥也不行,dp定义怎么也不能转移
然后看T2推了一会写了30分,然后打表找规律,线性筛拿到50分
最后一题就直接干暴力了,然后特判的时候数组用错了,然后越界了,然后爆蛋了
T1 环
环状的计数dp好多都是看分成了几段,然后一段一段的链接,然后就可以计数了
这个也是一样的,dp[i][j][k]表示前i个点,加入了j个单点,和k个链,直接转移
正解不重要了,就是合并转移,但是拆段的思想很重要
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<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=5005;
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;
}
int n,a[N];
int jc[N],inv[N];
int C(int x,int y){return jc[x]*inv[y]%mod*inv[x-y]%mod;}
int f[N][N],ans;
signed main(){
freopen("ring.in","r",stdin);
freopen("ring.out","w",stdout);
n=read();
fo(i,1,n)a[i]=read();
jc[0]=1;fo(i,1,n)jc[i]=jc[i-1]*i%mod;
inv[0]=1;inv[n]=ksm(jc[n],mod-2);
fu(i,n-1,1)inv[i]=inv[i+1]*(i+1)%mod;
sort(a+1,a+n+1);f[0][0]=1;
fo(i,1,n){
fo(j,0,a[i])f[i][j]=f[i-1][j];
fo(k,a[i-1]+1,a[i])fu(j,k,0)f[i][j+1]=(f[i][j+1]+f[i][j])%mod;
ans=(ans+f[i][1]-a[i])%mod;
fo(j,0,a[i])f[i][j-1]=(f[i][j-1]+f[i][j]*C(j,2)%mod*2)%mod;
}
// cerr<<f[n][1]<<endl;
ans=ans*ksm(2,mod-2)%mod;
// ans=f[n][1]*ksm(2,mod-2)%mod;
printf("%lld",ans);
return 0;
}
T2 数
找规律吧,然后类似min_25找素数个数和,筛一下模4余3的素数个数
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<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=4e5+5;
int n,ans,sq;
int p[N],cnt,sp1[N],sp2[N];bool vis[N];
void init_p(){
fo(i,2,sq){
if(!vis[i]){
p[++cnt]=i;
sp1[cnt]=sp1[cnt-1];
sp2[cnt]=sp2[cnt-1];
if(i%4==1)sp1[cnt]+=1;
if(i%4==3)sp2[cnt]+=1;
}
for(int j=1;j<=cnt&&i*p[j]<=sq;j++){
vis[i*p[j]]=true;
if(i%p[j]==0)continue;
}
}
}
int id1[N],id2[N],w[N*2],cw,g1[N*2],g2[N*2];
int calc(int n,int tp){
if(!n)return 0;cw=0;
for(int l=1,r;l<=n;l=r+1){
r=n/(n/l);w[++cw]=n/l;
if(tp){
g1[cw]=(w[cw]-1)/4;
g2[cw]=(w[cw]-3)/4+1;
}
else g1[cw]=w[cw]-1;
if(w[cw]<=sq)id1[w[cw]]=cw;
else id2[n/w[cw]]=cw;
}
if(tp){
fo(i,1,cnt)for(int j=1;j<=cw&&p[i]*p[i]<=w[j];j++){
int x=w[j]/p[i];x=(x<=sq)?id1[x]:id2[n/x];
if(p[i]%4==1){
g1[j]=g1[j]-(g1[x]-sp1[i-1]);
g2[j]=g2[j]-(g2[x]-sp2[i-1]);
}
if(p[i]%4==3){
g1[j]=g1[j]-(g2[x]-sp2[i-1]);
g2[j]=g2[j]-(g1[x]-sp1[i-1]);
}
}
return g2[1];
}
else {
fo(i,1,cnt)for(int j=1;j<=cw&&p[i]*p[i]<=w[j];j++){
int x=w[j]/p[i];x=(x<=sq)?id1[x]:id2[n/x];
g1[j]=g1[j]-g1[x]+i-1;
}
return g1[1];
}
}
signed main(){
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
// cerr<<(sizeof(p)+sizeof(vis)>>20)<<endl;
n=read();sq=sqrt(n);
init_p();
ans+=calc(n,1);
ans+=calc(n/4,0);
ans+=calc(n/16,0);
// cerr<<cnt<<endl;
printf("%lld",ans);
return 0;
}
T3 矩阵
很好的条件是操作在询问前,所以我们可以分治,x分治y用线段树搞
历史最大值!!!
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<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=5e4+5;
const int M=2e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
int n,m,Q,ans[M],C;
struct NOD{int xa,xb,ya,yb,w;}c[N],q[M];
#define ls x<<1
#define rs x<<1|1
struct XDS{
int mx[N*4],tg[N*4],ts[N*4],hs[N*4];
void pushup(int x){
mx[x]=max(mx[ls],mx[rs]);
hs[x]=max(hs[ls],hs[rs]);
}
void pushdown(int x){
if(ts[x]!=-inf){
hs[ls]=max(hs[ls],mx[ls]+ts[x]);
ts[ls]=max(ts[ls],tg[ls]+ts[x]);
hs[rs]=max(hs[rs],mx[rs]+ts[x]);
ts[rs]=max(ts[rs],tg[rs]+ts[x]);
ts[x]=-inf;
}
if(tg[x]){
mx[ls]+=tg[x];tg[ls]+=tg[x];
mx[rs]+=tg[x];tg[rs]+=tg[x];
tg[x]=0;
}
}
void build(int x,int l,int r){
ts[x]=-inf;if(l==r)return ;
int mid=l+r>>1;
build(ls,l,mid);build(rs,mid+1,r);
pushup(x);return ;
}
void ins(int x,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr){
tg[x]+=v;mx[x]+=v;
ts[x]=max(ts[x],tg[x]);
hs[x]=max(hs[x],mx[x]);
return ;
}
int mid=l+r>>1;if(tg[x]||ts[x]!=-inf)pushdown(x);
if(ql<=mid)ins(ls,l,mid,ql,qr,v);
if(qr>mid)ins(rs,mid+1,r,ql,qr,v);
pushup(x);return ;
}
int query(int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return hs[x];
int mid=l+r>>1,ret=-inf;if(tg[x]||ts[x]!=-inf)pushdown(x);
if(ql<=mid)ret=max(ret,query(ls,l,mid,ql,qr));
if(qr>mid)ret=max(ret,query(rs,mid+1,r,ql,qr));
pushup(x);return ret;
}
int qry(int x,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return mx[x];
int mid=l+r>>1,ret=-inf;if(tg[x]||ts[x]!=-inf)pushdown(x);
if(ql<=mid)ret=max(ret,qry(ls,l,mid,ql,qr));
if(qr>mid)ret=max(ret,qry(rs,mid+1,r,ql,qr));
pushup(x);return ret;
}
}xds;
vector<int> vcg[N*4],vcq[N*4],add[N],del[N],qry[N],sta[2][N*4];
void sol(int x,int l,int r){
if(!vcq[x].size())return ;
if(l==r)return ;int mid=l+r>>1,mx;
fo(i,l-1,r+1)add[i].clear(),del[i].clear(),qry[i].clear();
for(int i:vcg[x]){
if(c[i].xa<=mid){
int s=min(mid,c[i].xb),t=max(l,c[i].xa);
add[s].push_back(i);
del[t-1].push_back(i);
if(c[i].xa>l||c[i].xb<mid)vcg[ls].push_back(i);
else sta[0][x].push_back(i);
}
if(c[i].xb>mid){
int s=max(mid+1,c[i].xa),t=min(r,c[i].xb);
add[s].push_back(i);
del[t+1].push_back(i);
if(c[i].xb<r||c[i].xa>mid+1)vcg[rs].push_back(i);
else sta[1][x].push_back(i);
}
}
for(int i:vcq[x]){
if(q[i].xa<=mid+1&&q[i].xb>=mid){
if(q[i].xa<=mid)qry[q[i].xa].push_back(i);
if(q[i].xb>=mid+1)qry[q[i].xb].push_back(i);
}
else {
if(q[i].xb<mid)vcq[ls].push_back(i);
if(q[i].xa>mid+1)vcq[rs].push_back(i);
}
}
mx=xds.query(1,1,n,1,n)-C;xds.ins(1,1,n,1,n,mx);C+=mx;
fu(i,mid,l){
for(int j:del[i])xds.ins(1,1,n,c[j].ya,c[j].yb,-c[j].w);
for(int j:add[i])xds.ins(1,1,n,c[j].ya,c[j].yb,c[j].w);
for(int j:qry[i])ans[j]=max(ans[j],xds.query(1,1,n,q[j].ya,q[j].yb)-C);
}
for(int j:del[l-1])xds.ins(1,1,n,c[j].ya,c[j].yb,-c[j].w);
mx=xds.query(1,1,n,1,n)-C;xds.ins(1,1,n,1,n,mx);C+=mx;
fo(i,mid+1,r){
for(int j:del[i])xds.ins(1,1,n,c[j].ya,c[j].yb,-c[j].w);
for(int j:add[i])xds.ins(1,1,n,c[j].ya,c[j].yb,c[j].w);
for(int j:qry[i])ans[j]=max(ans[j],xds.query(1,1,n,q[j].ya,q[j].yb)-C);
}
for(int j:del[r+1])xds.ins(1,1,n,c[j].ya,c[j].yb,-c[j].w);
for(int i:sta[0][x])xds.ins(1,1,n,c[i].ya,c[i].yb,c[i].w);
sol(ls,l,mid);
for(int i:sta[0][x])xds.ins(1,1,n,c[i].ya,c[i].yb,-c[i].w);
for(int i:sta[1][x])xds.ins(1,1,n,c[i].ya,c[i].yb,c[i].w);
sol(rs,mid+1,r);
for(int i:sta[1][x])xds.ins(1,1,n,c[i].ya,c[i].yb,-c[i].w);
}
signed main(){
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
n=read();m=read();Q=read();
xds.build(1,1,n);
fo(i,1,m){
c[i].xa=read();c[i].ya=read();c[i].xb=read();c[i].yb=read();c[i].w=read();
vcg[1].push_back(i);
}
fo(i,1,Q){
q[i].xa=read();q[i].ya=read();q[i].xb=read();q[i].yb=read();
vcq[1].push_back(i);
}
sol(1,1,n);
fo(i,1,Q)printf("%lld\n",ans[i]);
}
QQ:2953174821