• 考试总结 模拟26


    心得:

    T1比较水,set水过,之前的有个达哥的等比数列的题,考场上忘了那道题怎么做了,虽然也做出来了

    T2思路很好想,但分数十分玄学,(不考虑细节+数据很水+代码很菜=50分玄学分数)

    T3很显然的dp,看着像一个单调队列,但也不怎么会,线段树学习一下其他人的打法

     

    题解

    T1

    一个贪心,对于每个数要尽量往前放,才能使块数更少,用一个set记录在当前块里的序列,若当前处理的数放入后会不符合要求,那就set清空,重新搞

    T2

    一个比较显然的图论题,对于取并集的情况,那就是这k个点向新点连边

    取交集的话是从新点向这k个点连边,

    但还要注意k==1时建双边,否则就会WA 0(理论上)

     1 //连有向边,<u,v>u信息在v中有,查询时就是看u能不能到v
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<cstdlib>
     7 #include<set>
     8 #define R register
     9 using namespace std;
    10 inline int read()
    11 {
    12     int f=1,x=0;char ch=getchar();
    13     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    15     return  x*f; 
    16 }
    17 const int maxn=1000000;
    18 struct node{
    19     int v,nxt;
    20 }e[maxn*2];int h[maxn],nu;
    21 void add(int x,int y)
    22 {
    23     e[++nu].v=y;
    24     e[nu].nxt=h[x];
    25     h[x]=nu;
    26 }
    27 int v[maxn];
    28 int dfs(int nw,int to)//环???
    29 {
    30     v[nw]=1;
    31     if(nw==to)return 1;
    32     for(int i=h[nw];i;i=e[i].nxt)
    33     {
    34         int y=e[i].v;
    35         if(v[y])continue;
    36         if(dfs(y,to))return 1;
    37     }
    38     return 0;
    39 }
    40 int main()
    41 {
    42 //    freopen("data","r",stdin);
    43     int tot=read(),m=read();
    44     while(m--)
    45     {
    46         int opt=read();
    47         if(opt)
    48         {
    49             int x=read(),y=read();
    50             memset(v,0,sizeof v);
    51             printf("%d
    ",dfs(x,y));
    52         }
    53         else 
    54         {
    55             int mot=read(),k=read();
    56             tot++;
    57             if(mot)
    58             {
    59                 for(int i=1;i<=k;++i)
    60                 {
    61                     int x=read();
    62                     add(x,tot);
    63                 }
    64             }
    65             else
    66             {
    67                 for(int i=1;i<=k;++i)
    68                 {
    69                     int x=read();
    70                     add(tot,x);
    71                 }
    72             }
    73         }
    74     }
    75 }
    76 /*
    77 g++ 2.cpp -o 2
    78 ./2
    79 
    80 */
    WA0

    建完双边还要考虑dfs不能死循环,否则MLE60(dfs爆栈)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<set>
     7 #define R register
     8 using namespace std;
     9 inline int read()
    10 {
    11     int f=1,x=0;char ch=getchar();
    12     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    14     return  x*f; 
    15 }
    16 const int maxn=1000000;
    17 struct node{
    18     int v,nxt;
    19 }e[maxn*2];int h[maxn],nu;
    20 void add(int x,int y)
    21 {
    22     e[++nu].v=y;
    23     e[nu].nxt=h[x];
    24     h[x]=nu;
    25 }
    26 int dfs(int nw,int to)
    27 {
    28     if(nw==to)return 1;
    29     for(int i=h[nw];i;i=e[i].nxt)
    30     {
    31         int y=e[i].v;
    32         if(dfs(y,to))return 1;
    33     }
    34     return 0;
    35 }
    36 int main()
    37 {
    38 //    freopen("data","r",stdin);
    39     int tot=read(),m=read();
    40     while(m--)
    41     {
    42         int opt=read();
    43         if(opt)
    44         {
    45             int x=read(),y=read();
    46             printf("%d
    ",dfs(x,y));
    47         }
    48         else 
    49         {
    50             int mot=read(),k=read();
    51             tot++;
    52             if(mot)
    53             {
    54                 for(int i=1;i<=k;++i)
    55                 {
    56                     int x=read();
    57                     add(x,tot);
    58                     if(k==1)add(tot,x);
    59                 }
    60             }
    61             else
    62             {
    63                 
    64                 for(int i=1;i<=k;++i)
    65                 {
    66                     int x=read();
    67                     add(tot,x);
    68                     if(k==1)add(x,tot);
    69                 }
    70             }
    71         }
    72     }
    73 }
    74 /*
    75 g++ 2.cpp -o 2
    76 ./2
    77 
    78 */
    MLE60

    如果用vis数组标记且每次memset,TLE50

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<set>
     7 #define R register
     8 using namespace std;
     9 inline int read()
    10 {
    11     int f=1,x=0;char ch=getchar();
    12     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    14     return  x*f; 
    15 }
    16 const int maxn=800000;
    17 struct node{
    18     int v,nxt;
    19 }e[maxn];int h[maxn],nu;
    20 void add(int x,int y)
    21 {
    22     e[++nu].v=y;
    23     e[nu].nxt=h[x];
    24     h[x]=nu;
    25 }    
    26 int v[maxn];
    27 int dfs(int nw,int to)
    28 {
    29     v[nw]=1;
    30     if(nw==to)return 1;
    31     for(int i=h[nw];i;i=e[i].nxt)
    32     {
    33         int y=e[i].v;
    34         if(v[y])continue;
    35         if(dfs(y,to))return 1;
    36     }
    37     return 0;
    38 }
    39 int main()
    40 {
    41 //    freopen("data","r",stdin);
    42     int tot=read(),m=read();
    43     while(m--)
    44     {
    45         int opt=read();
    46         if(opt)
    47         {
    48             int x=read(),y=read();
    49             memset(v,0,sizeof v);
    50             printf("%d
    ",dfs(x,y));
    51         }
    52         else 
    53         {
    54             int mot=read(),k=read();
    55             tot++;
    56             if(mot)
    57             {
    58                 for(int i=1;i<=k;++i)
    59                 {
    60                     int x=read();
    61                     add(x,tot);
    62                     if(k==1)add(tot,x);
    63                 }
    64             }
    65             else
    66             {
    67                 
    68                 for(int i=1;i<=k;++i)
    69                 {
    70                     int x=read();
    71                     add(tot,x);
    72                     if(k==1)add(x,tot);
    73                 }
    74             }
    75         }
    76     }
    77 }
    78 /*
    79 g++ 2.cpp -o 2
    80 ./2
    81 
    82 */
    TLE50

    然后就A了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<set>
     7 #define R register
     8 using namespace std;
     9 inline int read()
    10 {
    11     int f=1,x=0;char ch=getchar();
    12     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    14     return  x*f; 
    15 }
    16 const int maxn=800000;
    17 struct node{
    18     int v,nxt;
    19 }e[maxn];int h[maxn],nu;
    20 void add(int x,int y)
    21 {
    22     e[++nu].v=y;
    23     e[nu].nxt=h[x];
    24     h[x]=nu;
    25 }
    26 int dfs(int nw,int f,int to)
    27 {
    28     if(nw==to)return 1;
    29     for(int i=h[nw];i;i=e[i].nxt)
    30     {
    31         int y=e[i].v;
    32         if(y==f)continue;
    33         if(dfs(y,nw,to))return 1;
    34     }
    35     return 0;
    36 }
    37 int main()
    38 {
    39 //    freopen("data","r",stdin);
    40     int tot=read(),m=read();
    41     while(m--)
    42     {
    43         int opt=read();
    44         if(opt)
    45         {
    46             int x=read(),y=read();
    47             printf("%d
    ",dfs(x,0,y));
    48         }
    49         else 
    50         {
    51             int mot=read(),k=read();
    52             tot++;
    53             if(mot)
    54             {
    55                 for(int i=1;i<=k;++i)
    56                 {
    57                     int x=read();
    58                     add(x,tot);
    59                     if(k==1)add(tot,x);
    60                 }
    61             }
    62             else
    63             {
    64                 
    65                 for(int i=1;i<=k;++i)
    66                 {
    67                     int x=read();
    68                     add(tot,x);
    69                     if(k==1)add(x,tot);
    70                 }
    71             }
    72         }
    73     }
    74 }
    75 /*
    76 g++ 2.cpp -o 2
    77 ./2
    78 
    79 */
    Accept

     T3

    很神奇的堆优化

    $f[i]=min{f[j]+max(sum[i]-sum[j],b[j])}(i-k<=j<i)$

    那么转移的时候只需要考虑当前$f[j]+b[j]$和$f[j]-sum[j]$(j不一定相同,但要符合范围)中的最小值,

    所以分别存入堆中,第一个堆存f[j]+b[j],第二个存f[j]-sum[j],

    找到当前合法两个队顶的元素x1,x2,f[i]=min{x1,x2+sum[i]}

    那怎么处理对于每个j的max的问题?

    对于每个点先放第一个堆,

    在取第一个队顶元素的时候,若f[j]+b[j]<f[j]-sum[j]+sum[i],那就pop第一个堆,并放入第二个堆

    然后就可以愉快地解决了,当然还要先往堆中放一个极大值

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<set>
     7 #include<queue>
     8 #define INF 0x7ffffffffffffff
     9 #define ll long long
    10 #define R register
    11 using namespace std;
    12 inline int read()
    13 {
    14     int f=1,x=0;char ch=getchar();
    15     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    16     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    17     return  x*f; 
    18 }
    19 const int maxn=500005;
    20 inline ll min(ll x,ll y){return x<y?x:y;}
    21 inline ll max(ll x,ll y){return x<y?y:x;}
    22 int n,k;
    23 int a[maxn],b[maxn],sum[maxn];ll f[maxn];
    24 struct node{
    25     ll da;
    26     int id;
    27     bool friend operator < (node x,node y){
    28         return x.da>y.da;
    29     }
    30 };
    31 priority_queue<node>q1;
    32 priority_queue<node>q2;
    33 int main()
    34 {
    35     n=read(),k=read();
    36     for(R int i=1;i<=n;++i){
    37         a[i]=read(),
    38         sum[i]=sum[i-1]+a[i];
    39         f[i]=INF;
    40     }
    41     for(R int i=0;i<n;++i)
    42         b[i]=read();
    43     f[0]=0;
    44     node t;t.id=0,t.da=f[0]+b[0];
    45     q1.push(t);    
    46     t.da=INF,t.id=n+1;
    47     q1.push(t);
    48     q2.push(t);
    49     for(R int i=1;i<=n;++i)
    50     {
    51         node t1=q1.top();
    52         int j=t1.id;
    53         while(q1.size()&&(j<i-k||t1.da<f[j]-sum[j]+sum[i])){
    54             if(t1.da<f[j]-sum[j]+sum[i]){
    55                 node t;t.id=j,t.da=f[j]-sum[j];
    56                 q2.push(t);
    57             }
    58             q1.pop();
    59             t1=q1.top();j=t1.id;
    60         }
    61         node t2=q2.top();
    62         while(q1.size()&&t2.id<i-k)q2.pop(),t2=q2.top();
    63         f[i]=min(t1.da,t2.da+sum[i]);
    64         node t;t.da=f[i]+b[i],t.id=i;
    65         q1.push(t);
    66     }
    67     printf("%lld
    ",f[n]);
    68 }
    View Code
    愿你在迷茫时,记起自己的珍贵。
  • 相关阅读:
    《团队名称》第八次团队作业:Alpha冲刺
    《代码敲不队》第八次团队作业:Alpha冲刺 第四天
    《代码敲不队》第八次团队作业:Alpha冲刺 第三天
    《代码敲不队》第八次团队作业:Alpha冲刺 第二天
    《代码敲不队》第八次团队作业:Alpha冲刺 第一天
    【Beta】Scrum meeting 3
    【Beta】Scrum meeting 2
    《队长说得队》第九次团队作业:Beta冲刺与验收准备
    【Beta】Scrum meeting 1
    《队长说得队》【Alpha】Scrum meeting 5
  • 原文地址:https://www.cnblogs.com/casun547/p/11376351.html
Copyright © 2020-2023  润新知