第五周 8.8 --- 8.14

新的一周了诶..

8.8

做cf

看了一天博弈于是B想得好复杂..一直算 sg算不对..

c 是不懂要怎么处理 前 t 秒里面 没有被 2 操作 操作掉的数

cf 366 div2 c C - Thor

给每个节点 一个队列,队列里面存放的就是 对应它添加进来的时间,

在 3 操作 的时候,可以维护 一个位置 ,假如上次是操作到t1 那么这次的操作 就只需要 t1 到 t2就可以了

没想到把每一个时间当成一个东西丢进队列里面..

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <time.h>
 5 #include <math.h>
 6 #include <vector>
 7 #include <map>
 8 #include <set>
 9 #include <stack>
10 #include <queue>
11 #include <string>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 
16 typedef long long LL;
17 typedef pair<int,int> pii;
18 typedef pair<double,double> pdd;
19 const double eps = 1e-8;
20 const int INF = (1 << 30) - 1;
21 const int maxn = 300010;
22 int n,m,que[maxn];
23 queue<int> q[maxn];
24 
25 void solve(){
26     int op,x,t = 0,ans = 0,pos = 0;
27     memset(que,-1,sizeof(que));
28     for(int i = 1;i <= m;i++){
29         scanf("%d %d",&op,&x);
30         if(op == 1){
31             que[++t] = x;
32             q[x].push(t);
33             ans++;
34         }
35         else if(op == 2){
36             while(!q[x].empty()){
37                 int u = q[x].front();q[x].pop();
38                 que[u] = -1;
39                 ans--;
40             }
41         }
42         else{
43             int top = min(t,x);
44             for(int i = pos+1;i <= top;i++){
45                 if(que[i] == -1) continue;
46                 int v = que[i];
47                 q[v].pop();
48                 ans--;
49             }
50             pos = max(pos,top);
51         }
52         printf("%d\n",ans);
53     }
54 }
55 
56 int main(){
57     scanf("%d %d",&n,&m);
58     solve();
59     return 0;
60 }
View Code

 

8.9

早上做了周一他们比赛的题...还 wa着

下午做了一会儿多校...先不补

 

8.10

补8.8做的cf

Educational Codeforces Round 15

A.暴力

 

B.暴力,看别人的写法果然比自己简洁些..

首先 是 边算边用map存,然后就是 算 2的多少次方的时候用位运算,而我还在打表

 

C.离散化之后,顺着扫一遍,再倒着扫一遍.

看别人的写法,有直接去二分那个半径 r 然后check的

 

D. 推出公式,看斜率 为正还是 为负,来取 x 的值

然后还有些细节,可能 是 一直走路,一直开车,也可能 距离 d 不够开 一次车

还有一种 是 斜率为负的时候,开 x 次车,但是最后还剩一点 距离,就要再判断下是开车还是 走路

...看见q神 三分的姿势orz

 

E.一点都不会做..其实该好好想想,题目说了是 有向图这个条件,就相当于 一棵树 可以往上跳了

给出 一个 有向图,给出 k, 每条边的边权,求 点 i 的跳k个节点的路径上 的边权 和,和路径上的最小边权.

fa[k][i] 表示 i 节点 向上 跳 2^k 到的节点

sum[k][i] 表示 i 节点向上 跳2^k 的节点的路径上的边权和

mn[k][i] 表示 i 节点 向上跳 2^k 的节点 的路径上的边权的最小值

再像求LCA的时候预处理fa数组那样去更新

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <time.h>
 5 #include <math.h>
 6 #include <vector>
 7 #include <map>
 8 #include <set>
 9 #include <stack>
10 #include <queue>
11 #include <string>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 
16 typedef long long LL;
17 typedef pair<int,int> pii;
18 typedef pair<double,double> pdd;
19 const double eps = 1e-8;
20 const LL INF = (1LL << 35)-1;
21 const int maxn = 300010;
22 const int max_log = 35;
23 int fa[max_log][maxn];
24 LL mn[max_log][maxn],sum[max_log][maxn];
25 int n;
26 LL m;
27 
28 void solve(){
29     for(int k = 0;k+1 < max_log;k++){
30         for(int v = 0;v < n;v++){
31             if(fa[k][v] < 0) fa[k+1][v] = -1;
32             else{
33                 fa[k+1][v] = fa[k][fa[k][v]];
34                 sum[k+1][v] = sum[k][v] + sum[k][fa[k][v]];
35                 mn[k+1][v] = min(mn[k][v],mn[k][fa[k][v]]);
36             }
37         }
38     }
39     /*for(int k = 0;k < 5;k++){
40         printf("--------\n");
41         for(int v = 0;v < n;v++){
42             printf("fa[%d][%d] = %d\n",k,v,fa[k][v]);
43             printf("sum[%d][%d] = %d\n",k,v,sum[k][v]);
44             printf("mn[%d][%d] = %d\n",k,v,mn[k][v]);
45         }
46         printf("----------\n");
47     }*/
48     for(int i = 0;i < n;i++){
49         int u = i;
50         LL as = 0LL,am = INF;
51         for(int k = max_log-1;k >= 0;k--){
52             if(m & (1LL << k)) {
53                 as += sum[k][u];
54                 //printf("as = %I64d sum[%d][%d] = %I64d\n",as,k,u,sum[k][u]);
55                 am = min(am,mn[k][u]);
56                 u = fa[k][u];
57             }
58         }
59         printf("%I64d %I64d\n",as,am);
60     }
61 }
62 
63 int main(){
64     while(scanf("%d %I64d",&n,&m) != EOF){
65         memset(fa,-1,sizeof(fa));
66         for(int i = 0;i < n;i++) scanf("%d",&fa[0][i]);
67         for(int i = 0;i < n;i++) {
68             scanf("%I64d",&sum[0][i]);
69             mn[0][i] = sum[0][i]; 
70         }
71         solve();
72     }
73     return 0;
74 }
View Code

 

F.还没读懂题..过的人好少..感觉补不动..

 

8.11

做了下多校..

哈哈第一题从网络流想到并查集想到暴力..

还是没有想出来..

看题解是智商题...

 

8.12

补e

 

8.13

从昨晚开始看 e 

想到是一维的话可不可以用splay 来做...可是又不会splay..二维也不知道行不行

题解给的是 十字链表

dlx 里面用到的数据结构

看了别人的代码...还是改了一上午...还是搞不太清楚交换

cf 367 e E - Working routine

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1e3+5;
 8 int g[maxn][maxn],n,m,q,cnt;;
 9 
10 struct node{
11     int l,r,d,u;
12     int v;
13 }p[maxn*maxn];
14 
15 void solve(){
16     int x1,x2,y1,y2,w,h;
17     for(int j = 1;j <= q;j++){// h 是有好多行,w 是有好多列
18         scanf("%d %d %d %d %d %d",&x1,&y1,&x2,&y2,&h,&w);
19         int p1,p2,q1,q2;
20         p1 = g[x1][0];p2 = g[x2][0];
21         for(int i = 1;i <= y1;i++) p1 = p[p1].r;
22         for(int i = 1;i <= y2;i++) p2 = p[p2].r;
23         q1 = p1;q2 = p2;
24 
25         for(int i = 1;i <= w;i++){
26             swap(p[p[p1].u].d,p[p[p2].u].d);
27             swap(p[p1].u,p[p2].u);
28             if(i == w) break;
29             p1 = p[p1].r;p2 = p[p2].r;// p1,p2现在在矩形的末尾
30         }
31 
32         for(int i = 1;i <= h;i++){
33             swap(p[p[q1].l].r,p[p[q2].l].r);
34             swap(p[q1].l,p[q2].l);
35             swap(p[p[p1].r].l,p[p[p2].r].l);
36             swap(p[p1].r,p[p2].r);
37             if(i == h) break;
38             p1 = p[p1].d;p2 = p[p2].d;
39             q1 = p[q1].d;q2 = p[q2].d;
40         }
41         for(int i = 1;i <= w;i++){
42             swap(p[p[q1].d].u,p[p[q2].d].u);
43             swap(p[q1].d,p[q2].d);
44             q1 = p[q1].r;q2 = p[q2].r;
45         }
46     }
47     for(int i = 1;i <= n;i++){
48         int nxt = p[g[i][0]].r;
49         for(int i = 1;i <= m;i++) {
50             printf("%d ",p[nxt].v);
51             nxt = p[nxt].r;
52         }
53         printf("\n");
54     }
55 }
56 
57 int main(){
58     while(scanf("%d %d %d",&n,&m,&q) != EOF){
59         cnt = -1;
60         for(int i = 1;i <= n;i++) g[i][0] = ++cnt;
61         for(int i = 1;i <= m;i++) g[0][i] = ++cnt;
62         for(int i = 1;i <= n;i++){
63             for(int j = 1;j <= m;j++){
64                 ++cnt;
65                 scanf("%d",&p[cnt].v);
66                 g[i][j] = cnt;
67             }
68         }
69 
70         for(int i = 1;i <= n;i++){
71             for(int j = 1;j <= m;j++){
72                 int id = g[i][j];
73                 p[id].u = g[i-1][j];
74                 p[id].d = g[(i+1)%(n+1)][j];
75                 p[id].l = g[i][j-1];
76                 p[id].r = g[i][(j+1)%(m+1)];
77             }
78         }
79         for(int i = 1;i <= n;i++){
80             int id = g[i][0];
81             p[id].r = g[i][1];p[id].l = g[i][m];
82         }
83         for(int i = 1;i <= m;i++){
84             int id = g[0][i];
85             p[id].u = g[n][i];
86             p[id].d = g[1][i];
87         }
88         solve();
89     }
90     return 0;
91 }
View Code

 

感觉这样写的交换很繁..还是没有理解..sigh

 

补了多校 05 那道数位 dp

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/5747888.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值