省选模拟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]);
}
posted @ 2022-03-31 21:34  fengwu2005  阅读(81)  评论(0编辑  收藏  举报