• 10月9-11日连续大翻车实录


    10.9

    A.

    想到组合数……然后就没搞出来……

    正解只差一步:容斥原理……

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=(int)1e7+5,mod=998244353;
     7 int n,m,k;
     8 long long po[maxn];
     9 long long qpow(long long x,int tim)
    10 {
    11     long long tmp=1;
    12     for(;tim;tim>>=1,x=x*x%mod)
    13         if(tim&1)tmp=tmp*x%mod;
    14     return tmp;
    15 }
    16 long long inv[maxn];
    17 long long C(int n,int m)
    18 {
    19     inv[m]=inv[m]!=0?inv[m]:qpow(po[m],mod-2),inv[n-m]=inv[n-m]!=0?inv[n-m]:qpow(po[n-m],mod-2);
    20     return po[n]*inv[m]%mod*inv[n-m]%mod;
    21 }
    22 int haha()
    23 {
    24     po[0]=1;for(int i=1;i<=(int)1e7;i++)po[i]=po[i-1]*i%mod;
    25     scanf("%d%d%d",&n,&m,&k);
    26     if(n>m||1ll*n*k<1ll*m){puts("0");return 0;}
    27     long long ans=0;int sgn=1;
    28     for(int i=0;i<=n&&m-i*k-1>=n-1;i++)ans=(ans+sgn*C(n,i)*C(m-i*k-1,n-1)%mod+mod)%mod,sgn=-sgn;
    29     printf("%lld
    ",ans);
    30 }
    31 int sb=haha();
    32 int main(){;}
    A

    B.

    拓扑排序直接水过……

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=(int)1e6+5;
     7 struct node
     8 {
     9     int from,to,next;
    10 }edge[maxn<<1];
    11 int head[maxn],tot;
    12 void addedge(int u,int v)
    13 {
    14     edge[++tot]=(node){u,v,head[u]};head[u]=tot;
    15 }
    16 #include <stack>
    17 #include <queue>
    18 int belong[maxn],size[maxn],cnt,scnt,dfn[maxn],low[maxn],n,m;
    19 stack<int>s;
    20 void dfs(int root)
    21 {
    22     dfn[root]=low[root]=++cnt;s.push(root);
    23     for(int i=head[root];i;i=edge[i].next)
    24     {
    25         int v=edge[i].to;
    26         if(!dfn[v])dfs(v),low[root]=min(low[root],low[v]);
    27         else if(!belong[v])low[root]=min(low[root],dfn[v]);
    28     }
    29     if(low[root]==dfn[root])
    30     {
    31         int k;scnt++;
    32         do
    33         {
    34             k=s.top();s.pop();
    35             size[scnt]++;belong[k]=scnt;
    36         }while(k!=root);
    37     }
    38 }
    39 int dis[maxn],degree[maxn];
    40 queue<int>q;
    41 int haha()
    42 {
    43     scanf("%d%d",&n,&m);
    44     for(int i=1;i<=m;i++)
    45     {
    46         int x,y;scanf("%d%d",&x,&y);
    47         addedge(x,y);
    48     }
    49     for(int i=1;i<=n;i++)
    50         if(!dfn[i])dfs(i);
    51     memset(head,0,sizeof(head));
    52     for(int i=1;i<=m;i++)
    53     {
    54         int u=edge[i].from,v=edge[i].to;
    55         if(belong[u]!=belong[v])addedge(belong[u],belong[v]),degree[belong[v]]++;
    56     }
    57     int ans=0;
    58     for(int i=1;i<=scnt;i++)
    59         if(!degree[i])dis[i]=size[i],q.push(i),ans=max(ans,dis[i]);
    60     while(!q.empty())
    61     {
    62         int now=q.front();q.pop();
    63         for(int i=head[now];i;i=edge[i].next)
    64         {
    65             int v=edge[i].to;degree[v]--;dis[v]=max(dis[v],dis[now]+size[v]);
    66             if(!degree[v])ans=max(ans,dis[v]),q.push(v);
    67         }
    68     }
    69     printf("%d
    ",ans);
    70 }
    71 int sb=haha();
    72 int main(){;}
    B

    C.

    不可做啊……至今没人过……

    10.10

    A.

    妈的智障……瞎模拟一分没有……完全没注意到超过17一定可以实现……然后就可以大大减少枚举量……

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1000005;
     4 int n,a[18*maxn],b[18*maxn],f[18*maxn],A[maxn],B[maxn],id[maxn];
     5 inline bool cmp(const int &x,const int &y)
     6 {
     7     return B[x]<B[y];
     8 }
     9 int haha()
    10 {
    11     long long m;scanf("%d%lld",&n,&m);
    12     int ans=0;
    13     for(int i=1;i<=n;i++)scanf("%d%d",&A[i],&B[i]),id[i]=i;
    14     sort(id+1,id+n+1,cmp);
    15     for(int i=1;i<=n;i++)
    16     {
    17         if(B[id[i]]-B[id[i-1]]>17)b[i]=b[i-1]+18;else b[i]=b[i-1]+B[id[i]]-B[id[i-1]];
    18         a[b[i]]+=A[id[i]];
    19     }
    20     for(int i=1;i<=b[n];i++)
    21     {
    22         if(i==1||i==2||i==3||i==5||i==6||i==9||i==10||i==13||i==17)continue;
    23         f[i]=a[i];
    24         if(i>=7)f[i]+=max(f[i-4],f[i-7]);
    25         else if(i>=4)f[i]+=f[i-4];
    26         ans=max(ans,f[i]);
    27     }
    28     printf("%d
    ",ans);
    29 }
    30 int sb=haha();
    31 int main(){;}
    A

    B.

    想过多种策略……然而当时一一否决,包括正解……最后发现其实根本不需要考虑路径长度和是否真的是那个值……因为最终一定合法值最小……

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=35;
     4 int f[maxn][maxn][1775],a[maxn][maxn];
     5 int haha()
     6 {
     7     int t;scanf("%d",&t);
     8     while(t--)
     9     {
    10         int n,m;scanf("%d%d",&n,&m);
    11         for(int i=1;i<=n;i++)
    12             for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);
    13         memset(f,0x3f,sizeof(f));f[1][1][a[1][1]]=a[1][1]*a[1][1];
    14         for(int i=1;i<=n;i++)
    15             for(int j=1;j<=m;j++)
    16                 for(int k=0;k<=1770-a[i][j];k++)
    17                 {
    18                     f[i+1][j][k+a[i+1][j]]=min(f[i+1][j][k+a[i+1][j]],f[i][j][k]+a[i+1][j]*a[i+1][j]);
    19                     f[i][j+1][k+a[i][j+1]]=min(f[i][j+1][k+a[i][j+1]],f[i][j][k]+a[i][j+1]*a[i][j+1]);
    20                 }
    21         int ans=0x7f7f7f7f;
    22         for(int sum=1;sum<=1770;sum++)
    23         {
    24             if(f[n][m][sum]==0x3f3f3f3f)continue;
    25             ans=min(ans,(n+m-1)*f[n][m][sum]-sum*sum);
    26         }
    27         printf("%d
    ",ans);
    28     }
    29 }
    30 int sb=haha();
    31 int main(){;}
    B

    C.

    树归写挂……一份没有……

    最后发现最后四个二进制位记录个数就过了的我眼泪掉下来……

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=100005;
     4 struct node
     5 {
     6     int from,to,dis,next;
     7 }edge[maxn<<1];
     8 int head[maxn],tot;
     9 void addedge(int u,int v,int w)
    10 {
    11     edge[++tot]=(node){u,v,w,head[u]};head[u]=tot;
    12 }
    13 int n,m;
    14 int W[20];
    15 int dis[maxn],size[maxn],Q[maxn][20],delta[maxn],sonnum[maxn][20],f[maxn];
    16 void dfs1(int root,int fa)
    17 {
    18     size[root]=1;
    19     for(int i=head[root];i;i=edge[i].next)
    20     {
    21         int v=edge[i].to;int tmp=0;
    22         if(v!=fa)
    23         {
    24             dfs1(v,root);
    25             size[root]+=size[v];dis[root]+=dis[v];
    26             for(int j=0;j<16;j++)Q[root][j+edge[i].dis&15]+=Q[v][j],sonnum[v][j+edge[i].dis&15]+=Q[v][j],tmp+=W[j]*Q[v][j];
    27             Q[root][edge[i].dis&15]++,sonnum[v][edge[i].dis&15]++;
    28             f[root]+=f[v]-tmp+size[v]*edge[i].dis;
    29         }
    30     }
    31     for(int i=0;i<16;i++)delta[root]+=W[i]*Q[root][i];
    32     f[root]+=delta[root];
    33 }
    34 int g[maxn],P[maxn][20];
    35 void dfs2(int root,int fa)
    36 {
    37     for(int i=head[root];i;i=edge[i].next)
    38     {
    39         int v=edge[i].to;
    40         if(v!=fa)
    41         {
    42             int tmp=0,tmp2=0;
    43             for(int j=0;j<16;j++)
    44             {
    45                 tmp+=W[j]*Q[v][j];
    46                 P[v][j+edge[i].dis&15]+=P[root][j];
    47                 P[v][j+edge[i].dis&15]+=Q[root][j]-sonnum[v][j];
    48                 tmp2+=W[j]*P[root][j];
    49             }
    50             P[v][edge[i].dis&15]++;
    51             int convey=f[root]-delta[root]-(f[v]-tmp+edge[i].dis*size[v]);
    52             g[v]=convey+g[root]-tmp2+(n-size[v])*edge[i].dis;
    53             for(int j=0;j<16;j++)g[v]+=P[v][j]*W[j];
    54             dfs2(v,root);
    55         }
    56     }
    57 }
    58 int haha()
    59 {
    60     scanf("%d%d",&n,&m);
    61     for(int i=1;i<n;i++)
    62     {
    63         int x,y,z;scanf("%d%d%d",&x,&y,&z);
    64         addedge(x,y,z);addedge(y,x,z);
    65     }
    66     for(int i=0;i<16;i++)W[i]=(i^m)-i;
    67     dfs1(1,0);dfs2(1,0);
    68     for(int i=1;i<=n;i++)printf("%d
    ",f[i]+g[i]);
    69 }
    70 int sb=haha();
    71 int main(){;}
    C

    10.11     ——真·翻车

    A.

    没判重飞了70分……100->30

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=100005;
     4 int a[maxn],f[maxn],n;
     5 multiset<int>S;
     6 int gcd(int a,int b){return !b?a:gcd(b,a%b);}
     7 int haha()
     8 {
     9     scanf("%d",&n);
    10     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    11     f[1]=1;S.insert(a[1]);
    12     int gongcha=0;
    13     for(int i=2;i<=n;i++)
    14     {
    15         if(S.count(a[i])){S.clear();gongcha=0;f[i]=f[i-1]+1;S.insert(a[i]);continue;}
    16         S.insert(a[i]);
    17         multiset<int>::iterator it=S.lower_bound(a[i]),it2=it,it3=it;
    18         if(it!=S.begin())--it;
    19         ++it2;if(it2==S.end())--it2;
    20         if(it2==it3||it==it3)
    21         {
    22             gongcha=gcd(gongcha,(*it2)-(*it));
    23             if(gongcha<=1){S.clear();gongcha=0;S.insert(a[i]);f[i]=f[i-1]+1;continue;}
    24             f[i]=f[i-1];continue;
    25         }
    26         int bigger=(*it2),smaller=(*it);
    27         gongcha=gcd(gongcha,bigger-a[i]);gongcha=gcd(gongcha,a[i]-smaller);
    28         if(gongcha<=1){S.clear();gongcha=0;S.insert(a[i]);f[i]=f[i-1]+1;continue;}
    29         f[i]=f[i-1];
    30     }
    31     printf("%d
    ",f[n]);
    32 }
    33 int sb=haha();
    34 int main(){;}
    A

    B.

    没考虑集合大小为1时要建双向边日飞100分……100->0

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=500005;
     4 struct node
     5 {
     6     int from,to,next;
     7 }edge[maxn];
     8 int head[maxn],tot;
     9 void addedge(int u,int v)
    10 {
    11     edge[++tot]=(node){u,v,head[u]};head[u]=tot;
    12 }
    13 int n,m,num,tim,vis[maxn];
    14 int dfs(int now,int tar)
    15 {
    16     if(now==tar)return 1;vis[now]=tim;
    17     for(int i=head[now];i;i=edge[i].next)
    18     {
    19         int v=edge[i].to;
    20         if(vis[v]!=tim)
    21             if(dfs(v,tar))return 1;
    22     }
    23     return 0;
    24 }
    25 int haha()
    26 {
    27     scanf("%d%d",&n,&m);num=n;
    28     while(m--)
    29     {
    30         int opt;scanf("%d",&opt);
    31         if(!opt)
    32         {
    33             num++;int dir,sum;scanf("%d%d",&dir,&sum);
    34             for(int i=1;i<=sum;i++)
    35             {
    36                 int x;scanf("%d",&x);
    37                 if(sum==1){addedge(num,x),addedge(x,num);break;}
    38                 if(!dir)addedge(num,x);else addedge(x,num);
    39             }
    40         }
    41         else
    42         {
    43             tim++;int fr,to;scanf("%d%d",&fr,&to);
    44             printf("%d
    ",dfs(fr,to));
    45         }
    46     }
    47 }
    48 int sb=haha();
    49 int main(){;}
    B

    C.

    口胡了一个完全不对的单调队列结果操作完全错误炸飞50分……60->10

    实际上这个东西根本不能用单调队列……因为可以构造出某些数据,f数组极小,B数组极大,结果在更新单调队列时直接被扔掉,但其实后面它还可能成为最优解……(不过这样数据很难造吧……对拍两千多组数据都没错……)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=500005;
     4 struct node
     5 {
     6     int from,to,next;
     7 }edge[maxn];
     8 int head[maxn],tot;
     9 void addedge(int u,int v)
    10 {
    11     edge[++tot]=(node){u,v,head[u]};head[u]=tot;
    12 }
    13 int n,m,num,tim,vis[maxn];
    14 int dfs(int now,int tar)
    15 {
    16     if(now==tar)return 1;vis[now]=tim;
    17     for(int i=head[now];i;i=edge[i].next)
    18     {
    19         int v=edge[i].to;
    20         if(vis[v]!=tim)
    21             if(dfs(v,tar))return 1;
    22     }
    23     return 0;
    24 }
    25 int haha()
    26 {
    27     scanf("%d%d",&n,&m);num=n;
    28     while(m--)
    29     {
    30         int opt;scanf("%d",&opt);
    31         if(!opt)
    32         {
    33             num++;int dir,sum;scanf("%d%d",&dir,&sum);
    34             for(int i=1;i<=sum;i++)
    35             {
    36                 int x;scanf("%d",&x);
    37                 if(sum==1){addedge(num,x),addedge(x,num);break;}
    38                 if(!dir)addedge(num,x);else addedge(x,num);
    39             }
    40         }
    41         else
    42         {
    43             tim++;int fr,to;scanf("%d%d",&fr,&to);
    44             printf("%d
    ",dfs(fr,to));
    45         }
    46     }
    47 }
    48 int sb=haha();
    49 int main(){;}
    C

    我的分啊……………………………………………………………………

  • 相关阅读:
    CentOS yum 源的配置与使用
    在css当中使用opacity
    CSS position属性absolute relative等五个值的解释
    uni APP 微信小程序获取授权的微信信息
    vue-admin-element 打包发布后IE报错的问题
    RMAN恢复数据文件
    怎么删除表空间对应的某一个数据文件
    Oracle存储过程、函数、包加密wrap
    Oracle加密解密
    Interval 用法总结
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7652676.html
Copyright © 2020-2023  润新知