zoukankan      html  css  js  c++  java
  • [考试反思]0918csp-s模拟测试46:残存

    我。。。

    行吧大概说说。

    T1打的n2dp,什么随机化什么改变读入顺序都能AC。

    没想优化。打了个链表优化dp。不知为何WA了。

    T2读错题,死了。

    T3的50分暴力没来得及优化感觉思路很神仙(然而并没有特别神仙)

    打了3个对拍,T1还是一个spj对拍。然后各种AC。。。

    T2读错了题对拍显然也是错的。。

    呃啊。。。

    T2子任务测试点放错了,然后这次要重测。

    每次重测的题我都爆零(3次了),每次数据出锅导致我丢AC的都没有重测(2次)。

    Update:这次重测我的0分读错题代码变成了10分!!!

    T1:Set

    我曾经在想鸽巢原理会怎么考。

    这题挺好的,出题人的想法很好,但是他并没有尝试去卡那些乱搞的人。

    为什么模数是n呢。。。肯定有值得利用的地方。

    因为一共有n+1个位置的前缀和的值,而只有n种不同的取值。

    那么一定有重复的值,那么对应的两个位置做差就能被整除,所以这一段区间就是合法的。

    思路很棒!

     1 #include<cstdio>
     2 int n,x[1000005],lst[1000005],sum;
     3 int main(){
     4     scanf("%d",&n);
     5     for(int i=1;i<=n;++i)scanf("%d",&x[i]);
     6     lst[0]=1;
     7     for(int i=1;i<=n;++i){
     8         sum=(sum+x[i])%n;
     9         if(lst[sum]){printf("%d
    ",i-lst[sum]+1);for(int j=lst[sum];j<=i;++j)printf("%d ",j);return 0;}
    10         lst[sum]=i+1;
    11     }
    12 }
    View Code

    思路积累:

    • 鸽巢原理
    • 前缀和同余等价于区间和整除

    T2:Read

    书是可以换顺序的啊。。。。

    卡空间的情况下求众数出现次数是否大于一半。

    先求出现最多的数。

    那么出现这个数就是目前位置次数最多的就cnt++,否则--,cnt=0时更新这个值。

    这样的话如果它的数量超过一半的话就一定会有盈余。

    所以你最后记录下的数要么就是出现了超过一半次数的数(众数),要么就是一个没有意义的数。

    再跑一遍,判断这个数出现了几次就好了。

     1 #include<cstdio>
     2 int m,k,c[1005],X[1005],Y[1005],Z[1005],ans,id=1,cnt,tms,N;long long lst;
     3 int main(){
     4     scanf("%d%d",&m,&k);const int K=(1<<k)-1;
     5     for(int i=1;i<=m;++i)scanf("%d",&c[i]),N+=c[i];
     6     for(int i=1;i<=m;++i)scanf("%d",&X[i]);
     7     for(int i=1;i<=m;++i)scanf("%d",&Y[i]);
     8     for(int i=1;i<=m;++i)scanf("%d",&Z[i]);
     9     for(int i=1;i<=m;++i){
    10         lst=X[i];
    11         if(!cnt)id=lst,cnt++;else if(lst==id)cnt++;else cnt--;
    12         for(int j=2;j<=c[i];++j){
    13             lst=(lst*Y[i]+Z[i])&K;
    14             if(!cnt)id=lst,cnt++;else if(lst==id)cnt++;else cnt--;
    15         }
    16     }
    17     for(int i=1;i<=m;++i){
    18         lst=X[i];tms+=lst==id;
    19         for(int j=2;j<=c[i];++j)lst=(lst*Y[i]+Z[i])&K,tms+=lst==id;
    20     }
    21     if(tms>N-tms-1)printf("%d
    ",tms-(N-tms)-1);else puts("0");
    22 }
    View Code

    思路积累:

    • 模拟法求众数?
    • hash_map。(非正解)

    T3:Race

    遇到异或容易想到trie。

    可以发现,建出trie后,对于一个特定的数,我们把它的路径上的兄弟节点(m个)的权值记下来。

    设为st数组,那么其含义就是在一半的场次中,有st[i]个人的数同时比他大。(研究一下二进制然后看看trie就明白了)

    而st的每一位是自由组合的。

    暴力就是跑一边背包,记录每种排名的方案数,st就相当与物品,最后把排名与最终得分相乘。

    但是我们并没有利用题目中平方的性质。

    那个式子其实就是$ sum (st[i]+st[j]+st[k]+...+st[p])^2 $

    st在一半的情况中会出现在和式里。

    那么对于特定的i在一半的和式里会出现项$ st[i]^2 $

    对于特定的i和j,在一半的一半即1/4的情况里会同时在和式里出现,它们的贡献就是$ 2 imes st[i] imes st[j] $

    可以再合并合并式子也可以就此打住。

    反正把上面的答案加起来(可以m2枚举,也可以前缀和优化到m)之后乘上总方案数就是了。

    总方案数不要用快速幂,kxT90了(我也感觉不正常),直接左移就行了啊。。。

    代码实现极其简单。

     1 #include<cstdio>
     2 #define mod 1000000007
     3 int t[6300005][2],w[6300005],n,cnt,st[33],m,x[200005],rt,tot;
     4 void insert(int &p,int num,int al){
     5     if(!p)p=++cnt;
     6     w[p]++;
     7     if(al==-1)return;
     8     insert(t[p][(num&1<<al)?1:0],num,al-1);
     9 }
    10 void ask(int p,int num,int al){
    11     if(al==-1)return;
    12     st[al]=w[t[p][(num&1<<al)?0:1]];
    13     ask(t[p][(num&1<<al)?1:0],num,al-1);
    14 }
    15 int main(){
    16     scanf("%d%d",&n,&m);
    17     for(int i=1;i<=n;++i)scanf("%d",&x[i]),insert(rt,x[i],m-1);
    18     for(int i=1;i<=n;++i){
    19         ask(rt,x[i],m-1);
    20         long long ans=0;
    21         for(int i=0;i<m;++i)for(int j=i;j<m;++j)ans=(ans+1ll*st[i]*st[j])%mod;
    22         (ans<<=m-1)%=mod;
    23         tot^=ans;
    24     }printf("%d
    ",tot);
    25 }
    View Code

    思路积累:

    • 二进制与trie
    • 平方式的特点:拆开后每一项都是2次所以枚举是n2
    • 卡常是一种习惯:用位运算
  • 相关阅读:
    TCP/IP——IP网络协议简记
    TCP/IP——基础概念简记
    TCP/IP——链路层简记
    linux——(8)数据流重定向、管道命令
    linux——(7)了解shell
    linux——(6)vim与vi
    linux——(5)文件与文件系统的压缩与打包
    linux——(4)磁盘与文件系统管理
    linux——(3)文件与目录管理
    大数据--Spark原理
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11548126.html
Copyright © 2011-2022 走看看