• [考试反思]0226省选模拟32:磨灭


    被签到题$min25$爆干,被水题卡常,被恶心题吓走。

    其实$T3$本来应该拿$30$然而居然过掉了第一档然后搜索写挂了。

    $(!(($写成了$$$((!($然后就丢了$20$分。

    然而$T1$也还有$10$分的部分分没有来得及打,一个简单的自然数幂和。

    于是三道题的确都有一个橘红色的分数,加起来没有人家会的一个$min23$或者一个分类讨论题得的分多。

    $min25$筛到也不是不会,可是当时只学了思想并没有打板子。于是考场上并不敢花时间去现场实现。。。

    于是考场上一眼秒这大概是个$min25$然后就因为不会写而丢掉了。。。

    主要时间砸在$T2$上了,思路挺简单但是对$256$的内存感到不可思议,于是在那里边想边卡花了不少时间。

    $T3$没怎么往正道上想,部分分跟正解并没有什么关系然后就被带偏了。

    然后就没了。滚回去学$min25$板子就行了。

    T1:送你一道签到题

    大意:$sumlimits_{i=1}^{n}i^k  sumlimits_{a_1,a_2,a_3,...,a_n} [prodlimits_{j=1}^{m} a_j =j] sigma(a_1) sigma(a_2) ... sigma(a_m) ,n le 10^{10},m le 10^9,k le 10^3$

    一看这玩意是由若干积性函数拼起来的,猜测答案的$sumlimits_{i=1}^{n} f(i)$中的$f(i)$也就是关于$i$的积性函数。

    然后分解后发现它的确就是积性函数。在质数的值是个低次多项式($k$次),质数的某次幂的值也可以求。(类似背包再乘组合数)

    于是不难想到$min25$筛去求前缀和然后这题就没了。

    算是第一次写$min25$筛所以有不少想说的。。

    首先$min25$筛的第一步求$g$。在这道题里我们并不把$m$个数当作限制而是枚举最终有几个值不是$1$然后乘组合数来统计方案。

    所以我们要统计的实际上是$i^k$那一项。那么也就是个低次多项式了。

    $g$数组的初值是前缀和,于是在这道题里用得到自然数幂和,伯努利数或者插值任取。

    然后统计分配的方案数需要设$dp[i][j]$表示$i$个位置一共选了$p^j$的情况。(积性函数只考虑每种质数处的取值所以是$p^e$的形式)

    最后设$P(x)=sumlimits_{i} dp[i][x] inom{m}{i}$然后就可以在递归求解$S$的时候用了。

    然后就是到底是否包含$<sqrt{n}$的质数的问题,网上两种主流写法都是可以的但是貌似把质数保留的写法方便一些。

    大概要处理的东西挺多,阶乘,逆元,$g$,伯努利数,方案数$dp$,$P$,质数处的幂和。然而一步一步来看的话并不是很难理解。

    多做题也许就好了吧。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define Z 1111111
     4 #define ll long long
     5 #define mod 998244353
     6 ll n,v[Z],r;int m,k,g[Z],p[Z],pc,sq,o,x[Z],s[Z],X[Z],pw[Z],fac[Z],inv[Z],iv[Z],B[Z],dp[44][44],P[44],ppw[Z];
     7 int&get(ll a){return a<=sq?x[a]:X[n/a];}
     8 int C(int b,int t){return b<t||t<0?0:1ll*fac[b]*inv[t]%mod*inv[b-t]%mod;}
     9 int qp(ll b,int t,ll a=1){for(;t;t>>=1,b=b*b%mod)if(t&1)a=a*b%mod;return a;}
    10 int spow(int n,ll a=0){for(int i=0,p=n;i<=k;++i)a=(a+1ll*C(k+1,i+1)*p%mod*B[k-i])%mod,p=1ll*p*n%mod; return a*iv[k+1]%mod;}
    11 int S(ll x,int y,int a=0){
    12     if(x<=1||p[y]>x)return 0;
    13     for(int i=y,pe=1;1ll*p[i]*p[i]<=x&&i<=pc;++i)
    14         for(ll e=1,p0=p[i],p1=p0*p0,rt=ppw[i]; p1<=x ; ++e)
    15             a=(a+1ll*P[e]*rt%mod*S(x/p0,i+1)+1ll*P[e+1]*rt%mod*ppw[i])%mod, p0*=p[i],p1*=p[i],rt=rt*ppw[i]%mod;
    16     return (a+1ll*P[1]*(g[get(x)]-pw[y-1]+mod))%mod;
    17 }
    18 int main(){
    19     cin>>n>>m>>k;sq=sqrt(n);
    20     for(int i=fac[0]=1;i<Z;++i)fac[i]=1ll*fac[i-1]*i%mod;
    21     inv[Z-1]=qp(fac[Z-1],mod-2);
    22     for(int i=Z-2;~i;--i)inv[i]=inv[i+1]*(i+1ll)%mod,iv[i+1]=1ll*fac[i]*inv[i+1]%mod;
    23     for(int i=B[0]=1;i<k+3;++i)for(int j=0;j<i;++j)
    24         B[i]=(B[i]-1ll*B[j]*C(i+1,j)%mod*iv[i+1]%mod+mod)%mod; B[1]++;
    25     
    26     for(int i=dp[0][0]=1;i<40;++i)for(int j=i-1;j<40;++j)for(int z=39;z>j;--z)
    27         dp[i][z]=(dp[i][z]+dp[i-1][j]*(z-j+1ll))%mod;
    28     for(int j=1;j<40;++j)for(int i=1,C=m;i<=j;++i)
    29         P[j]=(P[j]+1ll*dp[i][j]*C)%mod,C=1ll*C*(m-i)%mod*iv[i+1]%mod;
    30     
    31     for(int i=2;i<=sq;++i){
    32         if(!s[i])p[++pc]=i,ppw[pc]=pw[pc]=s[i]=qp(i,k);
    33         for(int j=1;i*p[j]<=sq;++j){s[i*p[j]]=1ll*s[i]*s[p[j]]%mod;if(i%p[j]==0)break;}
    34     }
    35     for(int i=1;i<=sq;++i) s[i]=(s[i-1]+s[i])%mod;
    36     for(int i=1;i<=pc;++i) pw[i]=(pw[i]+pw[i-1])%mod;
    37     for(ll i=1,N,l;N=n/i,i<=n;i=l+1) l=n/N,v[get(N)=++o]=N,g[o]=N<=sq?s[N]:spow(N%mod)-1;
    38     for(int i=1;i<=pc;++i)for(int j=1;j<=o&&1ll*p[i]*p[i]<=v[j];++j)
    39         g[j]=(g[j]-1ll*ppw[i]*(g[get(v[j]/p[i])]-pw[i-1])%mod+mod)%mod;
    40     cout<<S(n,1)+1<<endl;
    41 }
    View Code

    T2:神渀

    大意:给定一个$012$数列以及一个权值序列,强制在线求每个点为右端点的子区间中,满足$012$个数互不相同的区间的最大异或和。$n le 3 imes 10^5$

    首先这个限制非常奇怪,区间出现次数互不相同。

    然而被不少题吊起来锤的我们总算会了点$trick$,直接差分。问题转变成差分也要互不相同。

    互不相同不好处理,但是相同貌似就好处理很多。

    最大异或和于是也不难想到建$01trie$。

    于是我们只需要维护$trie$的每个节点上,每种相同的值出现了多少次就好了,然后就可以根据$size$判断是否可以往那个方向走。

    然而我蠢了,为什么非得建一个$trie$然后上面维护那么多信息?时空常数太大。

    对于每种值都建一棵$trie$就好了。

    然而还是会被卡空间,又有一个神奇的$trick$.我们设$a=cnt0-cnt1,b=cnt1-cnt2,c=cnt0-cnt2$

    那么我们实际上是对于$a,b,c,ab,bc,ac,abc$这$7$种值都建$trie$

    然而实际上如果$ab$相同,那么就是$cnt1-cnt0,cnt2-cnt1$相同,那么就是$cnt2-cnt1+cnt1-cnt0=cnt2-cnt0=c$相同。

    那么就是$abc$相同。所以说后四个$trie$是完全一样的可以压成一个,于是就卡过去了。

    另外加一些优化,就是压一个儿子,或者压链。都能卡进$256MiB$的原限制。但是代码吗,就比较恶心了。。。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 300005ll
     4 #define Z 40000005
     5 map<int,int>rt[3];map<long long,int>RT;
     6 int p[S],A[S],n,c[2][Z],op,la,pc,cc[3],sz[Z],R;
     7 void insert(int&p,int w,int x=29){
     8     if(!p)p=++pc; sz[p]++; if(x<0)return;
     9     insert(c[w&1<<x?1:0][p],w,x-1);
    10 }
    11 int ask(int p,int p1,int p2,int p3,int p4,int w,int x=29){
    12     if(x<0)return 0;
    13     int o=w&1<<x?0:1;
    14     if(sz[c[o][p]]!=sz[c[o][p1]]+sz[c[o][p2]]+sz[c[o][p3]]-2*sz[c[o][p4]])return ask(c[o][p],c[o][p1],c[o][p2],c[o][p3],c[o][p4],w,x-1)|1<<x;
    15     o^=1;return ask(c[o][p],c[o][p1],c[o][p2],c[o][p3],c[o][p4],w,x-1);
    16 }
    17 int main(){
    18     cin>>n>>op;
    19     for(int i=1;i<=n;++i)scanf("%d",&p[i]);
    20     for(int i=1;i<=n;++i)scanf("%d",&A[i]);
    21     insert(R,0);insert(rt[0][0],0);insert(rt[1][0],0);insert(rt[2][0],0);insert(RT[0],0);
    22     for(int i=1;i<=n;++i){
    23         if(op)A[i]^=la,(p[i]^=la)%=3;cc[p[i]]++;A[i]^=A[i-1];
    24         int a=cc[1]-cc[0],b=cc[2]-cc[1],c=cc[2]-cc[0];
    25         la=(sz[rt[0][a]]+sz[rt[1][b]]+sz[rt[2][c]]-2*sz[RT[a*S+b]]==i)?0:ask(1,rt[0][a],rt[1][b],rt[2][c],RT[a*S+b],A[i]);
    26         printf("%d ",la); insert(R,A[i]); insert(rt[0][a],A[i]); insert(rt[1][b],A[i]); insert(rt[2][c],A[i]); insert(RT[a*S+b],A[i]);
    27     }
    28 }
    View Code

    T3:外挂

    大意:求$n imes m$的$01$矩阵中每个点,有多少种满足:所有的$1$可以被两个大小为$x imes y$的矩形完全覆盖。$n,m le 60$

    我也不知道为啥没想到。

    首先为了不重不漏,我们缩小包围圈$nm$保证四个边界上一定有人。这样的话只需要两层枚举边框大小就行。

    然后问题转化为:边框上一定有人且能被两个特定矩形覆盖的方案数。

    发现最优的覆盖方案一定是放在左上角,右下角。或者放在右上角,左下角。

    于是状压$6$维:是否有点已经在$4$个边界上,是否有点出现在了两种覆盖方法之外。

    然后就没了,逐个点讨论填不填的影响就行了。时间复杂度$O(2^6n^2m^2)$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 998244353
     4 int ans,n,m,x,y,pw[3666],dp[2][1<<6];
     5 void add(int&a,int b){a+=b;if(a>=mod)a-=mod;}
     6 int cal(int n,int m){
     7     int L=0,N=1,X=n-x+1,Y=m-y+1;
     8     for(int s=0;s<1<<6;++s)dp[L][s]=0;dp[L][0]=1;
     9     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j){
    10         for(int s=0;s<1<<6;++s)dp[N][s]=0;
    11         for(int s=0;s<1<<6;++s)add(dp[N][s|(i==1)<<5|(i==n)<<4|(j==1)<<3|(j==m)<<2|(!(i<=x&&j<=y)&&!(i>=X&&j>=Y))<<1|(!(i>=X&&j<=y)&&!(i<=x&&j>=Y))],dp[L][s]),add(dp[N][s],dp[L][s]);
    12         L^=1;N^=1;
    13     }return(0ll+dp[L][62]+dp[L][61]+dp[L][60])%mod;
    14 }
    15 int main(){
    16     cin>>n>>m>>x>>y;
    17     for(int i=pw[0]=1;i<=n*m;++i)pw[i]=(pw[i-1]<<1)%mod;
    18     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)ans=(ans+cal(i,j)*(n-i+1ll)%mod*(m-j+1))%mod;
    19     cout<<1+ans<<endl;
    20 }
    View Code
  • 相关阅读:
    Selenium3+python3自动化(三十九)--python3.7上SendKeys报错用PyUserInput取代
    Selenium3+python3自动化(三十八)--异常后截图(screnshot)、只截某个元素的图
    python学习6--python读取excel数据
    Selenium3+python3自动化(三十七)--捕获异常(NoSuchElementException)、try...except
    Selenium3+python3自动化(三十六)--expected_conditions模块 判断文本(text_to_be_present_in_element)
    Selenium3+python3自动化(三十五)--登录方法(参数化)
    Selenium3+python3自动化(三十四)--expected_conditions模块 判断弹出框存在(alert_is_present)
    Selenium3+python3自动化(三十三)--万能的js解决click()、clear()失效问题
    Selenium3+python3自动化(三十二)--4类32种定位方法(find_element_by_xx, find_elements_by_xx, find_element)
    Selenium3+python3自动化(三十一)--元素定位参数化(find_element)
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12373118.html
Copyright © 2020-2023  润新知