考试总结 模拟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]=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\n",f[n]);
68 }

原文地址:https://www.cnblogs.com/casun547/p/11376351.html

时间: 2024-07-30 20:10:17

考试总结 模拟26的相关文章

HDU 2100 Lovekey 模拟26进制

Problem Description XYZ-26进制数是一个每位都是大写字母的数字. A.B.C.-.X.Y.Z 分别依次代表一个0 ~ 25 的数字,一个 n 位的26进制数转化成是10进制的规则如下 A0A1A2A3-An-1 的每一位代表的数字为a0a1a2a3-an-1 ,则该XYZ-26进制数的10进制值就为 m = a0 * 26^(n-1) + a1 * 26^(n-2) + - + an-3* 26^2 + an-2*26 + an-1 一天vivi忽然玩起了浪漫,要躲在学校

考试总结 模拟99

考试过程 最后一场两位数的考试,死的很惨 开题后T1看了一眼,第一眼觉得是最长上升子序列,线性dp的那种 然后就去刚O(n)的算法,不久就听到大多数人敲键盘的声音,比较着急, 尤其是旁边人自信满满的动作....然后就通过写暴力稳定心态.写完之后没试样例就继续想 思考效率指数级降低...想要对旁边人予以“反击”,可还是没有思路 1h多后有看题发现样例过不了,虽然之前先看了一眼样例但是并不能把握每一个细节 又读了半天题最终在打算弃掉T1前读懂了... 浪费了1h30min??顿时一股来自西西伯利亚的

考试心得 模拟5

(本次考后总结 专门为 可能到来的某”特殊“访客 公开,其他的总结若有需要请与本人联系) 再次崩掉 0+30+5=35(排名33) 几乎每次都在30的边缘徘徊 先说过程: 考前:吃完饭后心态挺好,没有过度焦虑 坐下来,跟旁边人扯了一会loj的某运势,我————大凶,诸事不宜,但我不信邪,恩,心态完好 老师误把网断了,我以为用不着了就把浏览器关了,但当我再想打开的时候, 完了....凉了.... 被迫重启.... 关键是FTP被关了,,,编译的外部工具没了.......   *** 幸亏我会一点终

考试心得 模拟12

先干的T2  1个小时,啥都没打出来, 想到了线段树,分块,莫队,都能骗到不少分,但我都没想到怎么实现 其中有20分钟浪费在了没打完的线段树上,想好了再打,别浪费时间 T1 自己努力够到的天花板,只是别人的起跑线 找了10分钟规律,找到了父节点与儿子节点的关系,然后用手去打表,想要卡常,但你能不能先想到严密的思路再去用手码 又浪费了10分钟去摸索打表,然后发现没用,心思在打表卡常上卡了好久, 发现只能暴力建树,还有一个半小时结束考试,开始打,坑坑迟迟,lca板子不熟练,没信心 比往常数组多开成2

考试心得 模拟17

没有必要设密了,反正没人会关注渣渣 55+5+8=68(46) 似乎进了前50?哦不,sdfz走了,人少了,没人垫底了,更差了. 就算进了又怎样,干不到前20,省一都是扯淡 主要失败在: 自我要求:50分钟干完T1的60分算法,松懈,剩下的就没有思考了,不想多说了,比干坐着稍好点,多喝了点水,还能不生病,呵 思考时间:干完50分钟就死了,脑子已经不转了,连打哈欠, 还能提升的知识点: T1:不开longlong少5分 桶的运用优化时间, 特殊性质骗分 T2本次的最失败的题 什么都想不到,上次考了

考试报告 模拟24

T1 改题时遇到的问题: 1.搜索时只有树才可以dfs(int x,int f) 2.注意开long long!!!! 题解: 思路不难想(可我考场上还是没想出来),问最小距离的最大值,显然是个二分答案,考虑check(两点之间的距离),上边界和下边界分别抽象成一个点,能不能到,就是看路径上有没有完全阻断的路,那么就可以将每个点按照ans/2的半径作圆,如果有交集就将其连边,那么就从上边界开始dfs,若能找到下边界说明不行,剪枝:先将k个点按照横坐标升序排列,建边的时候如果距离>ans就不用建边

考试总结 模拟25

T1[A.字符串][catalan] Oh,no!!又一次出卡特兰数,又一次翻车,还是没有看出来??!! 可能是这次立志要刚出来一个dp题,所以就没怎么往数学那里想 不说了,40%的dp写了2个小时 T2[B.乌鸦喝水] 很好的一道思维题 首先每个缸都可以求出来最多能喝多少次,然后按照从小到大排序 一个十分显然的性质就是,前面的够删的话,后面的也够 从前往后枚举每个缸,比较这个缸剩余的删除次数和后面缸的个数 如果大于,那么就相当于这个缸对答案的贡献是其能减的层数,也就是已经进行的轮数,取余之后,

考试总结 模拟30

心得: 对于自己不确定会T多少的代码,一定不要瞎改,不要把自己之前的代码盖掉 题解: T1 读懂题后,sort+unique T2 一个裸的约瑟夫问题??然而垃圾的547并不知道约瑟夫是个什么,于是打了个队列模拟,从T10一直改到T60,然后被自己最后sb地给盖了 T3 很强的一道题 对于mod是非质数的情况 原文地址:https://www.cnblogs.com/casun547/p/11425639.html

考试总结 模拟62

很蒙的一场考试.一眼看过去暴力可拿5..5分??凉了. 最主要是没有难度顺序,然后就不知道该先干那个了.. T1T3都是个树,很没有思路,于是看T2, 然后发现似乎while(1)swap可以达到最后结果 但是会不会有不同的结果?换了个顺序拍了一下发现对拍过了 很兴奋试了组极限数据发现跟k的大小有关,然后很憋屈的以为只能拿到50分就弃了 然后看T3打完5分暴力输出过程检查,出乎意料的发现结果都是sum_w,大概yy了一会也不会证,只能分治看脸拿分 T1很郁闷以为是dp也没想到出想过两次的贪心 打