考试总结 模拟26

Posted casun547

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了考试总结 模拟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\n",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\n",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\n",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\n",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]=minf[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]=minx1,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\n",f[n]);
68 
View Code

 

以上是关于考试总结 模拟26的主要内容,如果未能解决你的问题,请参考以下文章

考试总结 模拟99

6.17考试总结(NOIP模拟8)

5.26 考试修改+总结

考试总结 NOIP模拟5 (20210608)

考试总结 模拟$102$

考试总结 模拟30