考试总结 模拟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 */
建完双边还要考虑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 */
如果用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 */
然后就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 */
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
以上是关于考试总结 模拟26的主要内容,如果未能解决你的问题,请参考以下文章