• 2017 多校联合训练 5 题解


    Problem 1001

    先预处理出一个数组,记录每个数对(x,y),y是x的倍数

    用一个bitset A把a数组记录下来

    然后用一个数组统计b数组

    再用s数组维护一个后缀,s[x]表示大于x所有出现的数的个数的奇偶性

    然后对于每一个未出现过的询问k,每个b数组中有的大于k的数,用bitset B记录它的倍数出现数的奇偶性

    最后答案为(A>>k)&B中1的奇偶行与s[k+1]的异或值

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cstring>
     7 #include<string>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #include<queue>
    12 #include<bitset>
    13 using namespace std;
    14 const int inf=(1<<30)-1;
    15 const int maxn=50010;
    16 #define REP(i,n) for(int i=(0);i<(n);i++)
    17 #define FOR(i,j,n) for(int i=(j);i<=(n);i++)
    18 typedef long long ll;
    19 typedef pair<int,int> PII;
    20 int IN(){
    21     int c,f,x;
    22     while (!isdigit(c=getchar())&&c!='-');c=='-'?(f=1,x=0):(f=0,x=c-'0');
    23     while (isdigit(c=getchar())) x=(x<<1)+(x<<3)+c-'0';return !f?x:-x;
    24 }
    25 #define MP make_pair
    26 #define fi first
    27 #define se second
    28 int n,m,q;
    29 int a[maxn],b[maxn],tot,k,ans[maxn];
    30 bitset<maxn> A,B,tmp;
    31 
    32 PII cnt[maxn*20];
    33 PII t[maxn];
    34 
    35 void init()
    36 {
    37     tot=0;
    38     for(int i=maxn-5;i>=1;i--)
    39         for(int j=i;j<=maxn-5;j+=i)
    40             cnt[++tot]=MP(i,j);
    41 }
    42 bool cmp(const PII &x,const PII & y) {return x.fi>y.fi;}
    43 bool vis[maxn],s[maxn];
    44 int main(){
    45     init();
    46     int T;scanf("%d",&T);
    47     while(T--)
    48     {
    49         A.reset();
    50         B.reset();
    51         memset(vis,0,sizeof(vis));
    52         memset(s,0,sizeof(s));
    53         n=IN();m=IN();q=IN();
    54         for(int i=1;i<=n;i++)
    55             a[i]=IN(),A[a[i]]=1;
    56         for(int i=1;i<=m;i++)
    57             b[i]=IN(),vis[b[i]]=1;
    58         for(int i=50000;i>=0;i--)
    59             s[i]=vis[i+1]^s[i+1];
    60         for(int i=1;i<=q;i++)
    61             t[i].fi=IN(),t[i].se=i;
    62         sort(t+1,t+q+1,cmp);
    63         int p=1;
    64         for(int i=1;i<=q;i++)
    65         {
    66             int k=t[i].fi;
    67             if(i>1&&k==t[i-1].fi) {
    68                 ans[t[i].se]=ans[t[i-1].se];
    69                 continue;
    70             }
    71             for(;p<=tot&&cnt[p].fi>k;p++)
    72                 if(vis[cnt[p].fi])
    73                 {
    74                     B[cnt[p].se]=B[cnt[p].se]^1;
    75                     //cout<<vis[cnt[p]].se<<" "<<vis[cnt[p]].fi<<endl;
    76                 }
    77             tmp=A>>k;
    78             tmp&=B;
    79             ans[t[i].se]=(tmp.count()&1);
    80             if(A[k]) ans[t[i].se]^=s[k];
    81         }
    82         for(int i=1;i<=q;i++) printf("%d
    ",ans[i]);
    83     }
    84     return 0;
    85 }
    View Code

    Problem 1002

    如果没有反字符串的限制,那么是一道经典的AC自动机

    预处理所有正串和反串的AC自动机
    从中间向两边dp

    然后暴力枚举从中间向左右的字符

    统计哪些串已经出现过

    这时可以暴力枚举dp的初始值

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstdlib>
      5 #include<algorithm>
      6 #include<cstring>
      7 #include<string>
      8 #include<vector>
      9 #include<map>
     10 #include<set>
     11 #include<queue>
     12 using namespace std;
     13 struct node
     14 {
     15     int next[2];
     16     int fail,flag;
     17     /*void init()
     18     {
     19         memset(next,0,sizeof(next));
     20         fail=0;
     21         flag=0;
     22     }*/
     23 } trie[200],T[200];
     24 int tot;
     25 void init()
     26 {
     27     tot=0;
     28     memset(trie,0,sizeof(trie));
     29 }
     30 void insert(char *str,int val)
     31 {
     32     int p=0,index,i,l=strlen(str);
     33     for (i=0;i<l;i++)
     34     {
     35         index=str[i]-'0';
     36         if (trie[p].next[index]==0)
     37         {
     38             trie[p].next[index]=++tot;
     39             //cout<<"hhhhhhh"<<endl;
     40         }
     41         p=trie[p].next[index];
     42     }
     43     trie[p].flag|=(1<<val);
     44 }
     45 int go[2][200][2],w[2][200];
     46 void build_fail(int pd)
     47 {
     48     queue<int> Q;
     49     /*int i;
     50     for (i=0;i<2;i++)
     51         if (trie[0].next[i])
     52             Q.push(trie[0].next[i]);
     53     while (!Q.empty())
     54     {
     55         int k=Q.front();
     56         trie[k].flag|=trie[trie[k].fail].flag;
     57         for (i=0;i<2;i++)
     58         {
     59             int j=trie[k].next[i];
     60             if (j==0) trie[k].next[i]=trie[trie[k].fail].next[i];
     61             else
     62             {
     63                 trie[j].flag|=trie[k].flag;
     64                 trie[j].fail=trie[trie[k].fail].next[i];
     65                 Q.push(j);
     66             }
     67         }
     68         Q.pop();
     69     }*/
     70     int p,son,cur,i;
     71     Q.push(0);
     72     while (!Q.empty())
     73     {
     74         p=Q.front();
     75         Q.pop();
     76         for (i=0;i<2;i++)
     77         {
     78             if (trie[p].next[i]!=0)
     79             {
     80                 son=trie[p].next[i];
     81                 cur=trie[p].fail;
     82                 if (p==0)
     83                     trie[son].fail=0;
     84                 else
     85                 {
     86                     while (cur&&trie[cur].next[i]==0)
     87                         cur=trie[cur].fail;
     88                     trie[son].fail=trie[cur].next[i];
     89                 }
     90                 trie[son].flag=trie[son].flag|trie[trie[son].fail].flag;
     91                 Q.push(son);
     92             }
     93             else
     94             {
     95                 trie[p].next[i]=trie[trie[p].fail].next[i];
     96             }
     97         }
     98     }
     99     for (i=0;i<=tot;i++)
    100     {
    101         go[pd][i][0]=trie[i].next[0];
    102         go[pd][i][1]=trie[i].next[1];
    103         w[pd][i]=trie[i].flag;
    104     }
    105     if (pd==0) memcpy(T,trie,sizeof(trie));
    106 }
    107 const int mo=998244353;
    108 int _,n,L;
    109 char s[11][31];
    110 int dp[2][70][130][130];
    111 void upd(int &x,int y)
    112 {
    113     x=(x+y)%mo;
    114 }
    115 int main()
    116 {
    117     scanf("%d",&_);
    118     while (_--)
    119     {
    120         init();
    121         scanf("%d%d",&n,&L);
    122         int i,j,k1,k2,k,len1,len2;
    123         for (i=1;i<=n;i++)
    124         {
    125             scanf("%s",s[i]);
    126             insert(s[i],i-1);
    127         }
    128         build_fail(0);
    129         len1=tot;
    130         init();
    131         for (i=1;i<=n;i++)
    132         {
    133             int l=strlen(s[i]);
    134             for (j=0;j<l;j++)
    135                 if (l-j-1>j) swap(s[i][j],s[i][l-j-1]);
    136         }
    137         for (i=1;i<=n;i++)
    138             insert(s[i],i-1);
    139         build_fail(1);
    140         len2=tot;
    141         for (i=1;i<=n;i++)
    142         {
    143             int l=strlen(s[i]);
    144             for (j=0;j<l;j++)
    145                 if (l-j-1>j) swap(s[i][j],s[i][l-j-1]);
    146         }
    147         memset(dp,0,sizeof(dp));
    148         int l=0;
    149         for (i=1;i<=n;i++)
    150             l=max(l,(int)strlen(s[i]));
    151         l=min(l,L);
    152         for (int W=0;W<(1<<l);W++)
    153         {
    154             int now=0,pd=0;
    155             for (i=0;i<l;i++)
    156             {
    157                 int k=((W&(1<<i))>0);
    158                 now=trie[now].next[k];
    159                 pd|=trie[now].flag;
    160             }
    161             for (i=l-1;i>=0;i--)
    162             {
    163                 int k=((W&(1<<i))==0);
    164                 now=trie[now].next[k];
    165                 pd|=trie[now].flag;
    166             }
    167             int k1=now;
    168             now=0;
    169             for (i=l-1;i>=0;i--)
    170             {
    171                 int k=((W&(1<<i))>0);
    172                 now=T[now].next[k];
    173             }
    174             dp[0][pd][now][k1]++;
    175             //cout<<0<<" "<<pd<<" "<<now<<" "<<k1<<endl;
    176         }
    177         int now=0;
    178         for (i=l+1;i<=L;i++)
    179         {
    180             int nex=now^1;
    181             int W=0;
    182             memset(dp[nex],0,sizeof(dp[nex]));
    183             for (j=0;j<(1<<n);j++)
    184                 for (k1=0;k1<=len1;k1++)
    185                     for (k2=0;k2<=len2;k2++)
    186                         if (W=dp[now][j][k1][k2])
    187                             for (k=0;k<2;k++)
    188                             {
    189                                 int k3=T[k1].next[k],k4=trie[k2].next[k^1];
    190                                 upd(dp[nex][j|T[k3].flag|trie[k4].flag][k3][k4],W);
    191                             }
    192             now=nex;
    193         }
    194         int ans=0;
    195         for (i=0;i<=len1;i++)
    196             for (j=0;j<=len2;j++)
    197                 upd(ans,dp[now][(1<<n)-1][i][j]);
    198         printf("%d
    ",ans);
    199     }
    200     return 0;
    201 }
    View Code

    Problem 1006

    m<n时连成一个菊花图

    m>=n时,剩下的每一条边将每一对点的距离缩减为1

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define rep(i, a, b)    for (int i(a); i <= (b); ++i)
     6 #define dec(i, a, b)    for (int i(a); i >= (b); --i)
     7 
     8 typedef long long LL;
     9 int T;
    10 LL n, m;
    11 LL ans;
    12 
    13 int main(){
    14 
    15 
    16     scanf("%d", &T);
    17     while (T--){
    18         scanf("%lld%lld", &n, &m);
    19         LL ans = n*n*n - n*n;
    20 
    21         LL dx = (n - 1) * 2;
    22         LL dy = dx - 2;
    23 
    24         if (m >= n){
    25             LL op = m;
    26             rep(i, 1, n - 1){
    27                 ans -= dx;
    28                 dx += dy;
    29             }
    30 
    31             LL yy = m - (n - 1);
    32             ans -= yy * 2;
    33 
    34             ans = max(ans, n * (n - 1));
    35             printf("%lld
    ", ans);
    36             
    37 
    38         }
    39 
    40         else{
    41             rep(i, 1, m){
    42                 ans -= dx;
    43                 dx += dy;
    44             }
    45 
    46             ans = max(ans, n * (n - 1));
    47 
    48             printf("%lld
    ", ans);
    49         }
    View Code

    Problem 1008

    从前往后枚举

    把缺的数补完整即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<cstring>
     7 #include<string>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #include<queue>
    12 using namespace std;
    13 typedef long long ll;
    14 int _,n,m;
    15 ll b[10010],now[10010],a[10010],as[10010],p[10010];
    16 ll C[61][61];
    17 void init()
    18 {
    19     int i,j;
    20     for (i=0;i<=50;i++)
    21     {
    22         C[i][0]=1;
    23         C[i][i]=1;
    24     }
    25     for (i=1;i<=50;i++)
    26         for (j=1;j<=50;j++)
    27             C[i][j]=C[i-1][j]+C[i-1][j-1];            
    28 }
    29 int main()
    30 {
    31     init();
    32     scanf("%d",&_);
    33     while (_--)
    34     {
    35         scanf("%d%d",&n,&m);
    36         int i,j,k;
    37         for (i=0;i<=m;i++)
    38             scanf("%lld",&b[i]);
    39         memset(now,0,sizeof(now));
    40         memset(a,0,sizeof(a));
    41         memset(p,0,sizeof(p));
    42         int t=0,tt=0;
    43         //cout<<b[0]<<" "<<now[1]<<endl;
    44         now[0]=1;
    45         for (i=1;i<=m;i++)
    46         {
    47             //cout<<i<<" "<<b[i]<<" "<<now[i]<<endl;
    48             if (now[i]<b[i])
    49             {
    50                 a[i]=b[i]-now[i];
    51                 //cout<<i<<" "<<now[6]<<endl;
    52                 tt+=a[i];
    53                 if (tt==n) break;        
    54                 int mx=0;
    55                 //if (t>m) break;
    56                 //if (a[i]>50) break;
    57                 //cout<<i<<" "<<t<<endl;
    58                 memset(p,0,sizeof(p));
    59                 for (j=1;j<=a[i];j++)
    60                 {
    61                     for (k=0;k<=t;k++)
    62                     {
    63                         ll x=0;
    64                         if (k+i*j>m) break;
    65                         p[k+i*j]+=now[k]*C[a[i]][j],mx=max(mx,k+i*j);
    66                         //if (k+i*j==6) cout<<i<<" "<<a[i]<<" "<<k<<" "<<now[k]<<" "<<C[a[i]][j]<<endl;
    67                         //cout<<k<<" "<<i<<" "<<j<<" "<<k+i*j<<" "<<now[k+i*j]<<endl;
    68                     }
    69                 }
    70                 t=mx;
    71                 for (j=0;j<=t;j++)
    72                 now[j]+=p[j];        
    73             }
    74         }
    75         int tot=0;
    76         for (i=1;i<=m;i++)
    77             for (j=1;j<=a[i];j++)
    78                 as[++tot]=i;
    79         for (i=1;i<tot;i++)
    80             printf("%lld ",as[i]);
    81         printf("%lld
    ",as[tot]);
    82     }
    83     return 0;
    84 }
    View Code

    Problem 1011

    排序后从最后一个数开始扫

    只要判断有多少对相邻的数的差<=k即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int inf=(1<<30)-1;
     4 const int maxn=100010;
     5 #define REP(i,n) for(int i=(0);i<(n);i++)
     6 #define FOR(i,j,n) for(int i=(j);i<=(n);i++)
     7 typedef long long ll;
     8 int n,k;
     9 int T;
    10 int a[maxn];
    11 int main()
    12 {
    13     scanf("%d",&T);
    14     while(T--)
    15     {
    16         scanf("%d%d",&n,&k);
    17         for(int i=1;i<=n;i++)
    18         scanf("%d",&a[i]);
    19         sort(a+1,a+n+1);
    20         int ans=1;
    21         for(int i=n;i>=2;i--)
    22         if(abs(a[i]-a[i-1])<=k) ans++;
    23         else break;
    24         printf("%d
    ",ans);
    25     }
    26     return 0;
    27 }
    View Code
  • 相关阅读:
    Java读写配置文件prop.properties
    java中int转String 固定位数 不足补零
    plantix插件工具,eclipse工具
    MongoDB API java的使用
    CSS定位细节
    Mysql 基于BinaryLog的复制
    Mysql之复制服务
    Linux 中文乱码问题解决
    Maven中手动引用第三方jar包
    innodb之超时参数配置
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/7441910.html
Copyright © 2020-2023  润新知