NOI模拟10

不得不说,和所有人比比看,我简直是菜到家了

看luogu上的题解,随便拿出一篇来,就说T1T2是签到题,我咋连暴力都签不上嘞...

考试过程中,可以说是完全没有策略,碰上啊这种难死一个都切不掉的时候就整个人都懵逼

我不敢撇下正解去打暴力,也是我没有时间写部分分的原因

可以尝试先把暴力打完再搞正解去,明天试一试这个策略..

T1 树

考场上只想到了指数级做法,但是忽略了一点,这个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<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=505;
int n,mod,ans;
int c[N][N],dp[N][N][N];
signed main(){
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
    n=read();mod=read();
    fo(i,0,n){
        c[i][0]=1;
        fo(j,1,i)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    }
    // cerr<<c[3][2]<<endl;
    fo(i,1,n)dp[1][1][i]=i;
    fo(i,1,n-1)fo(j,1,i)fo(k,1,n){
        dp[i+1][j][k]=(dp[i+1][j][k]-dp[i][j][k]*j*k*2%mod+mod)%mod;
        dp[i+1][j][k-1]=(dp[i+1][j][k-1]+dp[i][j][k]*j*(k-1))%mod;
        dp[i+1][j+1][k]=(dp[i+1][j+1][k]+dp[i][j][k]*j*k)%mod;
    }
    fo(i,1,n-1){
        ans=0;
        fo(j,0,i)ans=(ans+dp[i][j][1]*j)%mod;
        printf("%lld\n",ans);
    }
}

T2 众数

于是我一直在想是不是可以用线段树维护,但是众数显然是不可以用线段树维护的

但是线段树可以维护另外一个东西,就是占总个数百分之多少以上的,可以直接记录下前几个,当然这里用不到

所以我们不用想log的复杂度了,这样一看就是根号了,显然是不可以分块的

那就是根号分治了,对于同一种颜色的个数分类

大于的可以直接枚举,到时候枚举和其他颜色的贡献就行,先做个前缀和,这样就可以O(其他颜色数)统计了

那么只剩下小于和小于的了,可以扫描线...

学会算复杂度,这样一个暴力就能变成正解,剪一剪复杂度就对了...

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<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=2e5+5;
int T,n,sq,a[N],lsh[N],lh;
int mxn[N],ans;
vector<int> vec[N];
int pre[N],fro[N],pos[N];
void sol1(){
    fo(i,1,lh)if(vec[i].size()>sq){
        fo(j,1,n)pre[j]=pre[j-1]+(a[j]==i);
        fo(j,1,lh)if(j!=i){
            int mx=0,sz=vec[j].size();
            fo(k,0,sz-1){
                mx=max(mx,pre[vec[j][k]-1]-k+1);
                mxn[i]=max(mxn[i],mx+pre[n]-pre[vec[j][k]]+k);
            }
            mx=0;
            fo(k,0,sz-1){
                mxn[j]=max(mxn[j],mx+pre[vec[j][k]-1]-k+sz);
                mx=max(mx,k-pre[vec[j][k]]);
            }
            mxn[j]=max(mxn[j],mx+pre[n]);
        }
    }
}
int zs[N];
void sol2(){
    fo(i,1,n)if(vec[a[i]].size()<=sq){
        int sz=vec[a[i]].size();
        mxn[a[i]]=max(mxn[a[i]],zs[1]+sz-pos[i]);
        for(int j:vec[a[i]]){
            if(j==i)break;
            mxn[a[i]]=max(mxn[a[i]],zs[j+1]+sz-pos[i]+pos[j]+1);
        }
        for(int j:vec[a[i]]){
            int now=pos[i]-pos[j]+1;
            fu(p,j,1){
                if(zs[p]<now)zs[p]=now;
                else break;
            }
            if(j==i)break;
        }
    }
    fo(i,1,n)zs[i]=0;
}
signed main(){
    freopen("mode.in","r",stdin);
    freopen("mode.out","w",stdout);
    T=read();
    while(T--){
        lh=n=read();
        fo(i,1,n)lsh[i]=a[i]=read();
        sort(lsh+1,lsh+lh+1);lh=unique(lsh+1,lsh+lh+1)-lsh-1;
        if(lh<=5)sq=0;else sq=n;
        fo(i,1,n)a[i]=lower_bound(lsh+1,lsh+lh+1,a[i])-lsh;
        fo(i,1,n){
            if(vec[a[i]].size())fro[i]=vec[a[i]].back();
            else fro[i]=0;
            pos[i]=vec[a[i]].size();
            vec[a[i]].push_back(i);
        }
        sol1();sol2();
        fo(i,1,lh)vec[i].clear();
        reverse(a+1,a+n+1);
        fo(i,1,n){
            if(vec[a[i]].size())fro[i]=vec[a[i]].back();
            else fro[i]=0;
            pos[i]=vec[a[i]].size();
            vec[a[i]].push_back(i);
        }
        sol1();sol2();
        fo(i,1,lh)vec[i].clear();
        ans=0;
        fo(i,1,lh)ans=max(ans,mxn[i]);
        printf("%d\n",ans);
        fo(i,1,lh)if(mxn[i]==ans)printf("%d\n",lsh[i]);
        fo(i,1,lh)mxn[i]=0;
    }
    return 0;
}

T3 简单题

发现了一个大问题我的tarjan缩圆方树是错的,怪不得我调一年暴力也没有调出来...

没有观察性质,是在原图的基础上修改的,于是我们观察原图形态的特点

发现所有的环是梭子状的,于是缩圆方树,并且分类讨论即可...我没写。。。

posted @ 2022-05-16 21:55  fengwu2005  阅读(57)  评论(2编辑  收藏  举报