• 「csp-s模拟测试(9.18)」Set·Read·Race


    昨天考试考得有点迷???

    一看内存限制,T1 64MB T2 16MB 当场懵比.........

    T1 set

    考场打的背包问题和随机化,其实能randA掉,但不小心数组开小了????(长记性!!!!!

    正解的话因为每个前缀只需mod%n,所以有n+1个数,其中一定有重复的

    所以就可以O(n)扫了

    其实正解不难就是没有细想

     1 #include<bits/stdc++.h>
     2 #define MAXN 1100
     3 using namespace std;
     4 int read(){
     5     int x=0;char c=getchar();
     6     while(c<'0'||c>'9')c=getchar();
     7     while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
     8     return x;
     9 }
    10 int n;
    11 int a[MAXN*MAXN];
    12 struct node{int id,w;}e[1000001];
    13 int ans[MAXN];
    14 int pre[MAXN][1001];
    15 bool biao[2][MAXN];
    16 void work(){
    17      for(int i=1;i<=n;++i){
    18          e[i].id=i;e[i].w=a[i];
    19      }
    20      for(int i=1;i<=20000;++i){
    21          if(clock()>990000){
    22             printf("-1
    ");
    23             return ;
    24          }
    25          random_shuffle(e+1,e+n+1);
    26          int ok=0;int me=0;
    27          for(int j=1;j<=n;++j){
    28              me=(me+(e[j].w%n))%n;
    29              if(me==0){
    30                 ok=j;break;
    31              }
    32          }
    33          if(ok==0)continue;
    34          printf("%d
    ",ok);
    35          for(int j=1;j<=ok;++j)printf("%d ",e[j].id);
    36          return ;
    37      }
    38 }
    39 signed main(){
    40     n=read();
    41     for(int i=1;i<=n;++i){
    42         a[i]=read();a[i]%=n;
    43     }
    44     if(n>1000){
    45         work();
    46         return 0;
    47     }
    48     int now=1;int last=0;
    49     biao[last][0]=1;
    50     for(int i=1;i<=n;++i){
    51         for(int j=0;j<n;++j){
    52             if(biao[last][j]){
    53                biao[now][j]=1;
    54                pre[i][j]=0;
    55             }
    56             if(biao[last][j]){
    57                biao[now][(j+a[i])%n]=1;
    58                pre[i][(j+a[i])%n]=i;
    59             }
    60         }
    61         swap(now,last);
    62         memset(biao[now],0,sizeof(biao[now]));
    63     }
    64     swap(now,last);
    65     if(biao[now][0]==0){printf("-1
    ");return 0;}
    66     now=0;
    67     for(int i=n;i>=1;--i){
    68         if(pre[i][now]!=0)ans[++ans[0]]=pre[i][now];
    69         now=(now-a[pre[i][now]]%n+n)%n;        
    70     }
    71     if(ans[0]==0){printf("-1
    ");return 0;}
    72     printf("%d
    ",ans[0]);
    73     for(int i=1;i<=ans[0];++i){
    74         printf("%d ",ans[i]);
    75     }
    76     cout<<endl;
    77 }
    78 /*
    79 g++ pai.cpp -o pai
    80 ./pai
    81 g++ a.cpp -o a
    82 ./a
    83 */
    考场随机化暴力
     1 #include<bits/stdc++.h>
     2 #define MAXN 1100000
     3 #define int long long
     4 using namespace std;
     5 int vis[MAXN];int n,a[MAXN];
     6 signed main(){
     7      scanf("%lld",&n);
     8      vis[0]=0;
     9      for(int i=1;i<=n;++i){
    10          scanf("%lld",&a[i]);
    11      }int sum=0;
    12      for(int i=1;i<=n;++i){
    13          sum=(a[i]+sum)%n;
    14          if(vis[sum]!=0){
    15             printf("%lld
    ",i-vis[sum]);
    16             for(int j=vis[sum]+1;j<=i;++j){
    17                 printf("%lld ",j);
    18             }
    19             return 0;
    20          }
    21          vis[sum]=i;
    22      }
    23 }
    View Code

    T2 read

    考场时看出了答案其实就是2*maxn_sum-N-1,至于证明,除非最后时只剩一种类型的书了,不然肯定能接着放

    那么我们就可以直接判断了

    考场没算清内存其实1e6的数据是可以开数组的

    对于正解,定义一个id,cnt

    我们对于每个新出现的数,当cnt=0时id=当前数,不然id=当前数cnt++;否则cnt--;

    可以发现如果存在解的话,id一定为最大出现次数的值,但是因为可能中间存在非最大值之间互相抵消的情况

    所以还要再扫一边,判断当前值出现次数

     1 #include<bits/stdc++.h>
     2 #define MAXN 1100
     3 #define int long long
     4 using namespace std;
     5 int M,N,K;
     6 int co[MAXN],x[MAXN],y[MAXN],z[MAXN];int a[MAXN];
     7 int maxn_sum=0;int maxn;int S;
     8 signed main(){      
     9       scanf("%lld%lld",&M,&K);
    10       S=(1<<K)-1;
    11       for(int i=1;i<=M;++i)scanf("%lld",&co[i]);
    12       for(int i=1;i<=M;++i)scanf("%lld",&x[i]);
    13       for(int i=1;i<=M;++i)scanf("%lld",&y[i]);
    14       for(int i=1;i<=M;++i)scanf("%lld",&z[i]);
    15       N=0;int cnt=0;int id=0;
    16       for(int i=1;i<=M;++i){          
    17           long long last=x[i];
    18           N++;
    19           if(cnt==0){cnt=1;id=last;}
    20           else if(id==last){cnt++;}
    21           else if(id!=last){cnt--;}
    22           for(int j=1;j<co[i];++j) {
    23           last=(last*y[i]+z[i])&S;
    24           N=N+1;
    25               if(cnt==0){cnt=1;id=last;}
    26               else if(id==last){cnt++;}
    27               else if(id!=last){cnt--;}
    28         }
    29       } 
    30       if(cnt<1){printf("0
    ");return 0;}
    31       cnt=0;N=0;
    32       for(int i=1;i<=M;++i){
    33           long long last=x[i];
    34           N++;
    35           if(id==last){cnt++;}
    36           for(int j=1;j<co[i];++j) {
    37           last=(last*y[i]+z[i])&S;
    38           N=N+1;
    39               if(id==last){cnt++;}
    40         }          
    41       }
    42       if(2*cnt-N-1>0){printf("%lld
    ",2*cnt-N-1);}
    43       else printf("0
    ");
    44       /*scanf("%lld",&N);
    45       int cnt=0;int id=0;
    46       for(int i=1;i<=N;++i){scanf("%lld",&a[i]);}
    47       for(int i=1;i<=N;++i){
    48           long long last=a[i];     
    49           if(cnt==0){cnt=1;id=last;}
    50           else if(id==last){cnt++;}
    51           else if(id!=last){cnt--;}         printf("i=%lld
    ",i);  
    52       }
    53       if(cnt-1>0)printf("%lld
    ",cnt-1);
    54       else printf("%lld
    ",cnt);
    55       */
    56 }
    57 /*
    58 22
    59 1 3 3 3 3 2 2 2 2 1 1 1 1 1 1 1 1 1  1 1 1 1 
    60 */
    View Code

    T3 race

    咕了.............

    不咕。

    一道trie树好题,想了两节课,(在语文课上想题效率很高QAQ)

    首先对于x^2的转化:

       既然是排名,我们可以考虑成x^2,是每个大于他的数的集合相乘,即(x1+x2+x3+x4.....)*(x1+x2.......)

    (其中每个xi都为1),那么结果可以看成任意一个点对的贡献为一,答案就是点对的个数

    既然结果是求异或和,我们联想到trie树(这样说有些牵强.......)

    无论如何我们先建棵trie树

    那么从1-n的每个i,我们统计这个节点时单独考虑每一位的贡献,我们枚举一个j,一个k

    j(k)上的数表示在M-1位到j+1位的数与a[i]的这些位的数相等,那么如果使j,k同时大于a[i],我们只需

    确定好异或的第j,k位上的数,其他数随意,这样这两位上的数对他的贡献就是两个位的指针上的size*(1<<M-2)

    当j==k时乘的变成(1<<M-1),因为只需确定一位

     1 #include<bits/stdc++.h>
     2 #define int long long
     3 #define MAXN 210000
     4 using namespace std;
     5 int fa[MAXN][31];
     6 struct node{
     7      int ch[2];
     8      int size;
     9 }t[MAXN*20];int n,M;
    10 const int mod=1e9+7;
    11 int tot=1;int a[MAXN];
    12 void insert(int x){
    13      int p=1;t[p].size++;fa[x][M]=1;
    14      for(int i=M-1;i>=0;--i){
    15          int me=(a[x]>>i)&1;
    16          if(t[p].ch[me]==0)t[p].ch[me]=++tot;
    17          p=t[p].ch[me];
    18          t[p].size++;
    19          fa[x][i]=p;
    20      }
    21 }
    22 int ans[MAXN];
    23 void work(int x){
    24      for(int i=0;i<=M-1;++i){
    25          int me1=0,find1=0;int me2=0,find2=0;
    26          for(int j=0;j<i;++j){
    27              me1=(a[x]>>i)&1;me2=(a[x]>>j)&1;
    28              me1^=1;me2^=1;
    29              find1=fa[x][i+1];find2=fa[x][j+1];
    30              ans[x]=(ans[x]+2*t[t[find1].ch[me1]].size*t[t[find2].ch[me2]].size%mod*(1ll<<(M-2ll)))%mod;
    31          }
    32          me1=(a[x]>>i)&1;me1^=1;
    33          find1=fa[x][i+1];
    34          ans[x]=(ans[x]+t[t[find1].ch[me1]].size*t[t[find1].ch[me1]].size%mod*(1<<(M-1)))%mod;
    35      }
    36 }
    37 int sum=0;
    38 signed main(){
    39      scanf("%lld%lld",&n,&M);
    40      for(int i=1;i<=n;++i){
    41          scanf("%lld",&a[i]);
    42      }
    43      for(int i=1;i<=n;++i){insert(i);}
    44      for(int i=1;i<=n;++i){work(i);}
    45      for(int i=1;i<=n;++i){
    46          sum^=ans[i];
    47      }
    48      printf("%lld
    ",sum);
    49 }
    View Code

    ******************************

    思路积累:

    x^2的转化,

    trie树的应用,

    比较大小只需考虑每一位的贡献

  • 相关阅读:
    RESTful API 设计指南
    理解RESTful架构
    django-mysqlclient_1193错误
    获取当前脚本所在的目录和路径
    20191007
    20191005
    20191001
    20190927
    20190922
    莫比乌斯反演证明
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11548363.html
Copyright © 2020-2023  润新知