[考试反思]1002csp-s模拟测试57:平庸

一天两场,感觉要完。

不粘排行榜,太壮观了。

#1:190

#2:180

#4:160

#35:150

#37:140

#39:120

#kx:20呃。。。

最后一个是考试结束后了。

又是CE盖40分。其实离#2不远。。。

调试语句没删干净,开O2编译出一条编译错误,没看,以为是那条关于scanf的warning。

然而并不是。

一定要仔细检查编译信息!!!交代码前一定要编译!!!

还有其实T1险些出锅,看错了题。

考试结束前7分钟重新看了一遍发现不对劲,+100pts。

看题!!!

要检查!!!

T1:

不会讲。写的超麻烦。

 1 #include<cstdio>
 2 main(){
 3     int t;scanf("%d",&t);
 4     while(t--){
 5         int a,b,c,x,y,z;scanf("%d%d%d%d%d%d",&a,&b,&c,&x,&y,&z);
 6         int det=(x>a)+(y>b)+(z>c);
 7         if(det==0){puts("YES");continue;}
 8         if(det==3){puts("NO");continue;}
 9         if(det==2){
10             if(a>=x)puts(a-x>>1>=y-b+z-c?"YES":"NO");
11             if(b>=y)puts(b-y>>1>=x-a+z-c?"YES":"NO");
12             if(c>=z)puts(c-z>>1>=x-a+y-b?"YES":"NO");
13         }
14         if(det==1){
15             if(x>a)puts(x-a<=(b-y>>1)+(c-z>>1)?"YES":"NO");
16             if(y>b)puts(y-b<=(a-x>>1)+(c-z>>1)?"YES":"NO");
17             if(z>c)puts(z-c<=(a-x>>1)+(b-y>>1)?"YES":"NO");
18         }
19     }
20 }

T2:

数据范围显然状压n,但是状压表示什么?

因为要造DAG,所以一定有拓扑序,就存哪些点已经被拓扑了就行。

但是有的DAG的拓扑序不唯一。要容斥掉。(容斥系数我会证了感谢吧人擦)

枚举补集的子集,枚举子集的高效方法一直不会,上网颓了一个。

for(int st=S;st;(--st)&=S);这样st就会遍历S的所有子集。

这题也严重卡常,不能通过直接枚举n来判断二进制下是否存在这个点,而是要lowbit来直接取出一位。

 1 #include<cstdio>
 2 #define mod 1000000007
 3 int fir[18],l[299],to[299],cnt,n,m,cr[18],sz[1666666],pre[18],re[1666666];
 4 long long pw[111],dp[1666666];
 5 void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;}
 6 main(){//freopen("obelisk8.in","r",stdin);
 7     dp[0]=pw[0]=1;
 8     scanf("%d%d",&n,&m);
 9     for(int i=1,x,y;i<=m;++i)scanf("%d%d",&x,&y),link(x,y);
10     for(int st=1;st<1<<n;++st)sz[st]=sz[st^st&-st]+1;
11     for(int i=1;i<=n;++i)re[1<<i-1]=i;
12     for(int i=1;i<=100;++i)pw[i]=(pw[i-1]<<1)%mod;
13     for(int i=1;i<=n;++i)for(int j=fir[i];j;j=l[j])pre[i]|=1<<to[j]-1;
14     for(int st=0;st<1<<n;++st)
15         for(int U=(~st)&(1<<n)-1,S=U;S;(--S)&=U){
16             int cnt=0;
17             for(int i=st;i;i^=i&-i)cnt+=sz[S&pre[re[i&-i]]];
18             (dp[st|S]+=dp[st]*pw[cnt]*(sz[S]&1?1:-1)%mod+mod)%=mod;
19         }
20     printf("%lld\n",dp[(1<<n)-1]);
21 }

思路积累:

  • DAG-dp:拓扑序的状态压缩
  • 神奇容斥

T3:

40%的暴力写在黑板上了,其实不M的话是60,附个代码。

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 int n,pr[30000005],md[100000005],prcnt;
 5 bool np[100000005];long long Ans=1;short ans[100000001],mdcnt[100000001];
 6 int main(){
 7     scanf("%d",&n);
 8     for(int i=2;i<=n;++i){
 9         if(!np[i])ans[i]=3,pr[++prcnt]=i,mdcnt[i]=1,md[i]=i;
10         for(int j=1;j<=prcnt&&i*pr[j]<=n;++j){
11             int T=i*pr[j];
12             md[T]=pr[j];np[T]=1;
13             mdcnt[T]=md[i]==pr[j]?mdcnt[i]+1:1;
14             ans[T]=ans[i]/(mdcnt[T]*2-1)*(mdcnt[T]*2+1);
15             if(i%pr[j]==0)break;
16         }
17     }
18     for(int i=2;i<=n;++i)Ans+=ans[i];
19     printf("%lld\n",(1ll*n*n-Ans)%1000000007);
20 }

另一种40~60的打法是cbx的,在下面说。

第一鸡房的不少都是用反演A的,我太菜我不会。

我跟cbx走的。

疯狂的数论分块就好了。

问题就是怎么求下发题解里的f函数,求出f值后就可以在外层数论分块n/d做了。

观察f数组,把它差分一下得到g,g[k]是什么含义?

是[gcd(a,b)==1]×a×b==k的a,b对数。

考虑含义,既然乘积一定,那么把k分解质因数之后把因子分配给ab就好了。

如果一种因子有多个,那么一定只分给ab里的一个,否则gcd不为1。

那么其实g[k]的值就是2k的质因子种数(不是个数)。可以线筛

然后做一遍前缀和就可以得到f了。

怎么求S函数呢?一个比较直接的数论分块。

然后对于大的f值就可以递归求了。

没有想象的那么难,虽然不是很会证。

 1 #include<cstdio>
 2 #define int long long
 3 #define mod 1000000007
 4 int pr[8000005],md[10000005],prcnt,f[10000005];
 5 bool np[10000005];int n,Ans;
 6 int S(int k){
 7     int ans=0;
 8     for(int i=1,lst;i<=k;i=lst+1)lst=k/(k/i),(ans+=(lst-i+1)%mod*(k/i))%=mod;
 9     return ans;
10 }
11 int F(int k){
12     if(k<=10000000)return f[k];int ans=0;
13     for(int j=2;j*j<=k;++j)(ans+=F(k/j/j))%=mod;
14     return (S(k)-ans+mod)%mod;
15 }
16 main(){
17     scanf("%lld",&n);f[1]=1;
18     for(int i=2;i<=10000000;++i){
19         if(!np[i])f[i]=2,pr[++prcnt]=i,md[i]=i;
20         for(int j=1;j<=prcnt&&i*pr[j]<=10000000;++j){
21             int T=i*pr[j];
22             md[T]=pr[j];np[T]=1;
23             f[T]=(f[i]<<(md[i]!=pr[j]))%mod;
24             if(i%pr[j]==0)break;
25         }
26     }
27     for(int i=2;i<=10000000;++i)(f[i]+=f[i-1])%=mod;
28     for(int i=1,lst;i<=n;i=lst+1)lst=n/(n/i),(Ans+=(lst-i+1)%mod*F(n/i)+mod)%=mod;
29     printf("%lld\n",(n%mod*(n%mod)%mod-Ans+mod)%mod);
30 }

思路积累:

  • 数论分块:竟然是联赛知识点啊
  • 线筛:肯定是联赛知识点

原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11619374.html

时间: 2024-08-30 16:39:28

[考试反思]1002csp-s模拟测试57:平庸的相关文章

csps模拟测试57

T1 天空龙 大神题,考察多方面知识,例如:快读 附上考试代码,以供后人学习 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 inline int read() 7 { 8 int x=0,f=1;char c=getchar(); 9 while(c<'0'||c>'9') {if

csp-s模拟测试57(10.2)「天空龙」&#183;「巨神兵」&#183;「太阳神」

题目是古埃及神话??? A. 天空龙 傻逼模拟,看来没有滑天下之大稽QAQ,也没有打错快读(大雾...) B. 巨神兵 难度爆增,一脸懵比..... 60分状压: 因为是求有向图,关于有向图好像拓扑用的很多,考虑到每个图的拓扑序是一定的 那么我们可以借此转移,设f[i][j]为当前点的状态为i,出度为零的点的度数为j 向下一层转移时枚举下一层的点集,那么点集S中每个点一定要和j连边,可以和i中除j以外的点连边 然后对于每个点cnt1,表示除j以外与i的连边,cnt2表示与j的连边,该点的贡献为2

CSP-S 模拟测试57题解

人生第一次A,B层一块考rank2,虽然说分差没几分,但还是值得纪念. 题解: T1 天空龙: 大神题,因为我从不写快读也没有写考场注释的习惯,所以不会做,全hzoi就kx会做,kx真大神级人物. T2 巨神兵: 大神题,一看数据范围这么小,我们考虑状压,最傻逼的暴力思路是压边,但是这显然不行.正解是压点,设$f[s]$为当前选定点集状态为$s$的方案数. 我们考虑转移,当前选定的点集肯定是可以通过边和没有连过来的点相连构成新的方案.所以转移所以我们考虑枚举补集的子集$k$,设$cnt$为s与k

模拟测试57

T1: 贴心送分题. 对于每种颜色,如果多了,就会有多的数量除二的贡献,反之会有少的数量的需求. 最后判断贡献和需求哪个大即可. 时间复杂度$O(1)$. T2: 边数太多,考虑将状态记录在点上. 每一种可行方案是一个dag,可以按照拓扑序列分层. 状态记录当前选中的集合,和最后一层的点的集合,然后枚举状态更新即可. 更新时算出当前集合向拓展集合连的边数,每个点至少要有一条入边. 考虑优化,省去第二维状态. 枚举补集的子集,算出当前集合向拓展集合连的边数,每条边都可以连或不连. 但是这样会算重,

[考试反思]0929csp-s模拟测试55:沦陷

菜得过分. 面对T1的大板子不知所措,然后T2的贪心不小心把排序语句删了... T1这种大模板啊...其实我是觉得我能打出来的,然后先用一个小时码了一个2k. 然后做T2想贪心就出来了.十分钟码完T3暴力之后回T1打对拍瞬间爆炸. 于是又重新打了一个2k,WA0.对拍发现. 然后考试就没几分钟了交暴力走了. 不要打完就跑,记得早点对拍改进思路. T1: 的确是挺裸的线段树.离散化或者权值线段树都可以. 但是考场上两个都打出来都死了. 最后用离散化A的. 1 #include<cstdio> 2

[考试反思]1002csp-s模拟测试56:凌乱

放假回来状态回升??(玩够了-但是稍困) T1打的不完全对,但是过掉了.很快的想到了二分吧喇叭啦.. 然后T2也挺快想出来了但是挂细节没发现,考试快结束的时候才发现出锅了. 改了过来是正解,但是出题人无良卡了线段树强制树状数组,T了一个子任务,卡常到飞起. T3暴力没什么问题. 卡常是一种习惯.要注意题目数据范围观察是否卡常. T1: 所有的决策都是一条一次函数. 分两类,斜率正或斜率非负. 如果第二类的直线里有在T=0时符合要求的,那么答案就是0,所以check(0)一下. 如果非负的直线都在

[考试反思]1003csp-s模拟测试58:沉淀

稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使用的话,切记计算内存,一点都不能开大. T1: 直接根号筛,拿map也能过. 遍历map直接begin和end啊... 1 #include<cstdio> 2 int Cnt[202]; 3 struct hash_map{ 4 int cnt,fir[10000020],l[6666666],

[考试反思]0114省选模拟7:迷离

这次考得相对不错,但是没什么水准. 只不过记得T1这道原题而已.虽说我忘了怎么做,而且数据范围不一样...差不多是从头想的. 但是并没有AC,像个弱智一样,有两个细节写的完全不对还有80分运气也是真好. 其实挂了不止两个细节...以为是原题于是上来就写20分钟写完,然后过一会出一个锅... 然后看T2,感觉$O(nk^2)$也许差不多?常数很大...但也不会别的.挺好想但是不是很好写. 于是乎强烈谴责cbx没素质暴力水题考后还不改正解的无脸行径 于是就开始写,写了一个半小时. 看T3,绝对大神题

模拟测试68,69

68: 32 AlpaCa 41 03:08:20 31 02:46:16 30 02:46:28 102 03:08:20 69: 28 AlpaCa 20 02:51:15 60 03:05:32 0 01:39:45 80 03:05:32 彻底挂掉了呢. 不过也还好吧,至少之后的考试不会有那么大压力了吧(出第一机房是肯定的事了),那利用之后几场考试就调整好状态,下次再来嘛. 但是最近炸了那么多场还是要反思一下,其实不只是心态的问题,自身实力,考试技巧,时间分配等方面好像都有点问题. 69