第十九周 7.4 --- 7.10

新的一周,惯例地加油>.<

 

7.4

 leetcode 114 Flatten Binary Tree to Linked List

把一颗二叉树拉成一个链表,不能够使用额外的空间

不会捉,看的题解了

如果 一个节点,没有右子树的话,直接把左子树挪到右子树就可以了

如果 一个节点没有左子树的话,就不用管

如果 一个节点既有左子树,又有右子树,就把右子树放在左子树的前序遍历的最后一个节点的后面,这样就变成 第一种情况了,再把左子树接过去

 1 class Solution{
 2 public:
 3     void flatten(TreeNode* root){
 4         if(root == NULL) return;
 5         while(root){
 6             if(root->left != NULL){
 7                 TreeNode* node = root->left;
 8                     while(node->right != NULL){
 9                         node = node->right;
10                     }
11                     node->right = root->right;
12                     root->right = root->left;
13                     root->left = NULL;
14                 }
15             root = root->right;
16         }
17     }
18 };
View Code

 

话说 leetcode 是越来越难上了...一道题要pending 半个小时..TAT

 

cf 223 div2 e Sereja and Brackets

给出一个长度为 n 的括号序列,m 个询问区间[l,r] 有多少个完整的括号

一开始 想到去dp,可是n 为 1e6,还去前缀搞了一发,根本不对嘛

完全没有想到是线段树嘛...

 

维护 一个左括号的个数,右括号的个数,完整的括号的个数

但是按照普通的求区间和来写的话,这样的查询区间 就不对

比如样例的

1  2  3 4   5  6   7   8  9   10  11      12

(  )  )  (  (  )  )  (  (  )  )  (

像 [5,6] 这样跨过 区间的,就不对了,后来看了别人的写法,可是自己还是 不太会啊

看frog 姐姐博客说的,没有看懂的代码一定不要往上抄,最后肯定会害了自己......

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1e6+5;
 8 int lc[maxn<<2],rc[maxn<<2],sum[maxn<<2],L[maxn<<2],R[maxn<<2];
 9 int n,ql,qr;
10 char s[maxn];
11 
12 void Push_up(int o){
13     int tmp = min(lc[o<<1],rc[o<<1|1]);
14     sum[o] = sum[o<<1] + sum[o<<1|1] + tmp*2;
15     lc[o] = lc[o<<1] + lc[o<<1|1] - tmp;
16     rc[o] = rc[o<<1] + rc[o<<1|1] - tmp;
17 }
18 
19 void Build(int o,int l,int r){
20     L[o] = l;R[o] = r;
21     if(l == r){
22         lc[o] = rc[o] = sum[o] = 0;
23         if(s[l] == '(') lc[o] = 1;
24         else rc[o] = 1;
25         return;
26     }
27     int mid = (l+r)/2;
28     Build(o<<1,l,mid);
29     Build(o<<1|1,mid+1,r);
30     Push_up(o);
31 }
32 
33 int Query(int o,int l,int r,int &nl,int &nr){
34     if(ql <= l && r <= qr){
35         nl = lc[o];
36         nr = rc[o];
37         return sum[o];
38     }
39     int mid = (l+r)/2;
40     if(qr <= mid) return Query(o<<1,l,mid,nl,nr);
41     else if(ql > mid) return Query(o<<1|1,mid+1,r,nl,nr);
42     else{
43         int sum1,sum2,nll,nrr,tmp;
44         sum1 = Query(o<<1,l,mid,nl,nr);
45         sum2 = Query(o<<1|1,mid+1,r,nll,nrr);
46         tmp = min(nl,nrr);
47         nl = nl+nll-tmp;
48         nr = nr+nrr-tmp;
49         return sum1+sum2+tmp*2;
50     }
51 }
52 
53 void solve(){
54     n = strlen(s+1);
55     Build(1,1,n);
56     int m,u,v;
57     scanf("%d",&m);
58     int tmpl,tmpr;
59     for(int i = 1;i <= m;i++){
60         scanf("%d %d",&u,&v);
61         ql = u;qr = v;
62         printf("%d\n",Query(1,1,n,tmpl,tmpr));
63     }
64 }
65 
66 int main(){
67     while(scanf("%s",s+1) != EOF){
68         solve();
69     }
70     return 0;
71 }
View Code

后来看题解,还有 一种这样的实现方法  

Codeforces 380C - Sereja and Brackets (线段树括号匹配)

 

7.5

补题叭..补题叭..

cf 347 div2 a A - Complicated GCD

很简单的题,但是没有读对题意,直接去套大数 gcd了

是要求 能够被区间 [a,b] 的所有的数整除 的最大的 d

  1 #include <stdio.h>
  2 #include <math.h>
  3 #include <string.h>
  4 #include <iostream>
  5 #include <string>
  6 #include <algorithm>
  7 using namespace std;
  8 
  9 const int numlen = 105;
 10 
 11 int max(int a, int b) { return a>b?a:b; }
 12 struct bign {
 13     int len, s[numlen];
 14     bign() {
 15         memset(s, 0, sizeof(s));
 16         len = 1;
 17     }
 18     bign(int num) { *this = num; }
 19     bign(const char *num) { *this = num; }
 20     bign operator = (const int num) {
 21         char s[numlen];
 22         sprintf(s, "%d", num);
 23         *this = s;
 24         return *this;
 25     }
 26     bign operator = (const char *num) {
 27         len = strlen(num);
 28         while(len > 1 && num[0] == '0') num++, len--;
 29         for(int i = 0;i < len; i++) s[i] = num[len-i-1] - '0';
 30         return *this;
 31     }
 32 
 33     void deal() {
 34         while(len > 1 && !s[len-1]) len--;
 35     }
 36 
 37     bign operator + (const bign &a) const {
 38         bign ret;
 39         ret.len = 0;
 40         int top = max(len, a.len) , add = 0;
 41         for(int i = 0;add || i < top; i++) {
 42             int now = add;
 43             if(i < len) now += s[i];
 44             if(i < a.len)   now += a.s[i];
 45             ret.s[ret.len++] = now%10;
 46             add = now/10;
 47         }
 48         return ret;
 49     }
 50     bign operator - (const bign &a) const {
 51         bign ret;
 52         ret.len = 0;
 53         int cal = 0;
 54         for(int i = 0;i < len; i++) {
 55             int now = s[i] - cal;
 56             if(i < a.len)   now -= a.s[i];
 57             if(now >= 0)    cal = 0;
 58             else {
 59                 cal = 1; now += 10;
 60             }
 61             ret.s[ret.len++] = now;
 62         }
 63         ret.deal();
 64         return ret;
 65     }
 66     bign operator * (const bign &a) const {
 67         bign ret;
 68         ret.len = len + a.len;
 69         for(int i = 0;i < len; i++) {
 70             for(int j = 0;j < a.len; j++)
 71                 ret.s[i+j] += s[i]*a.s[j];
 72         }
 73         for(int i = 0;i < ret.len; i++) {
 74             ret.s[i+1] += ret.s[i]/10;
 75             ret.s[i] %= 10;
 76         }
 77         ret.deal();
 78         return ret;
 79     }
 80 
 81     //乘以小数,直接乘快点
 82     bign operator * (const int num) {
 83         bign ret;
 84         ret.len = 0;
 85         int bb = 0;
 86         for(int i = 0;i < len; i++) {
 87             int now = bb + s[i]*num;
 88             ret.s[ret.len++] = now%10;
 89             bb = now/10;
 90         }
 91         while(bb) {
 92             ret.s[ret.len++] = bb % 10;
 93             bb /= 10;
 94         }
 95         ret.deal();
 96         return ret;
 97     }
 98 
 99     bign operator / (const bign &a) const {
100         bign ret, cur = 0;
101         ret.len = len;
102         for(int i = len-1;i >= 0; i--) {
103             cur = cur*10;
104             cur.s[0] = s[i];
105             while(cur >= a) {
106                 cur -= a;
107                 ret.s[i]++;
108             }
109         }
110         ret.deal();
111         return ret;
112     }
113 
114     bign operator % (const bign &a) const {
115         bign b = *this / a;
116         return *this - b*a;
117     }
118 
119     bign operator += (const bign &a) { *this = *this + a; return *this; }
120     bign operator -= (const bign &a) { *this = *this - a; return *this; }
121     bign operator *= (const bign &a) { *this = *this * a; return *this; }
122     bign operator /= (const bign &a) { *this = *this / a; return *this; }
123     bign operator %= (const bign &a) { *this = *this % a; return *this; }
124 
125     bool operator < (const bign &a) const {
126         if(len != a.len)    return len < a.len;
127         for(int i = len-1;i >= 0; i--) if(s[i] != a.s[i])
128             return s[i] < a.s[i];
129         return false;
130     }
131     bool operator > (const bign &a) const  { return a < *this; }
132     bool operator <= (const bign &a) const { return !(*this > a); }
133     bool operator >= (const bign &a) const { return !(*this < a); }
134     bool operator == (const bign &a) const { return !(*this > a || *this < a); }
135     bool operator != (const bign &a) const { return *this > a || *this < a; }
136 
137     string str() const {
138         string ret = "";
139         for(int i = 0;i < len; i++) ret = char(s[i] + '0') + ret;
140         return ret;
141     }
142 
143     void print(){
144         for(int i = len-1;i >= 0;i--) printf("%d",s[i]);
145         printf("\n");
146     }
147 };
148 istream& operator >> (istream &in, bign &x) {
149     string s;
150     in >> s;
151     x = s.c_str();
152     return in;
153 }
154 ostream& operator << (ostream &out, const bign &x) {
155     out << x.str();
156     return out;
157 }
158 
159 bign gcd(bign a, bign b) {
160     while(b != 0) {
161         bign tmp = a%b;
162         a = b; b = tmp;
163     }
164     return a;
165 }
166 
167 bign a,b,ans;
168 
169 int main() {
170     cin >> a >> b;
171     if(a != b) puts("1");
172     else a.print();
173     return 0;
174 }
View Code

 

cf 347 div2 bB - Rebus

上一次提交这题 是 4月18号...sigh...而且wa13之后,就没再补了...TwT\

给出 ?+?-?= n,其中问号填 1 到 n 的数字,问能不能够构成等式

补题的时候有个地方没想清楚,所以一直 wa

如果 平均下来 的值都大于 n 了的话,肯定构不成

如果 正的是 0 的话,就给它添成 1,再多减,看最后能不能满足

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 string s;
 9 int zh[105],fu[105];
10 
11 int change(string t){
12     int res = 0;
13     int len = t.length();
14     for(int i = 0;i < len;i++){
15         res = res*10+t[i]-'0';
16     }
17     return res;
18 }
19 
20 void solve(){
21     int c1 = 1,c2 = 0,n;
22     int len = s.length();
23     string tmp;
24     for(int i = 0;i < len;i++){
25         if(s[i] == '+') c1++;
26         if(s[i] == '-') c2++;
27         if(s[i] >= '0' && s[i] <= '9') tmp += s[i];
28     }
29     n = change(tmp);
30     //printf("c1 = %d c2 = %d n = %d\n",c1,c2,n);
31     int ave = (n+c2)/c1;
32     int cnt = (n+c2)%c1;
33     //printf("cnt = %d\n",cnt);
34     memset(zh,0,sizeof(zh));
35     memset(fu,0,sizeof(fu));
36 
37     int flag = 0,tot = 0;
38     for(int i = 1;i <= c1;i++){
39         if(i <= cnt) zh[i] = ave+1;
40         else zh[i] = ave;
41         if(zh[i] > n){
42             puts("Impossible");
43             return;
44         }
45         if(zh[i] == 0){
46             tot++;
47             zh[i] = 1;
48         }
49     }
50     for(int i = 1;i <= c2;i++) fu[i] = 1;
51     //for(int i = 1;i <= c1;i++) printf("zh[%d] = %d\n",i,zh[i]);
52     if(tot){
53         int ok = 0;
54         for(int i = 1;i <= c2;i++){
55             int pp = min(n-1,tot);
56             fu[i] += pp;
57             tot -= pp;
58             if(tot <= 0){
59                 ok = 1;
60                 break;
61             }
62         }
63         if(ok == 0){
64             puts("Impossible");
65             return;
66         }
67     }
68     
69     puts("Possible");
70     int p1 = 1,p2 = 1;
71     for(int i = 0;i < len;i++){
72         if(i == 0) printf("%d",zh[p1++]);
73         else if(s[i] == '?' && s[i-2] == '+') printf("%d",zh[p1++]);
74         else if(s[i] == '?' && s[i-2] == '-') printf("%d",fu[p2++]);
75         else printf("%c",s[i]);
76     }
77     printf("\n");
78 }
79 
80 int main(){
81     getline(cin,s);
82     solve();
83     return 0;
84 }
View Code

 

7.6

cf 348div2 d D - Little Artem and Dance

注意到奇的,偶的 它们的相对位置不会变,所以模拟 1 和 2的位置就可以了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1e6+5;
 8 int n,q;
 9 int ans[maxn];
10 
11 void solve(){
12     int cmd,x;
13     int c1 = 1,c2 = 2;
14     for(int i = 1;i <= q;i++){
15         scanf("%d",&cmd);
16         if(cmd == 1){
17             scanf("%d",&x);
18             c1 = (c1+n+x)%n;
19             c2 = (c2+n+x)%n;
20         }
21         else{
22             if(c1%2 == 0){
23                 c1 = (c1-1+n)%n;
24                 c2 = (c2+1+n)%n;
25             }
26             else{
27                 c1 = (c1+1+n)%n;
28                 c2 = (c2-1+n)%n;
29             }
30         }
31         if(c1 == 0) c1 = n;
32         if(c2 == 0) c2 = n;
33     //    printf("i = %d c1 = %d c2 = %d \n",i,c1,c2);
34     }
35 
36     for(int i = 1;i <= n;i++){
37         int id;
38         if(i&1) id = (i+c1-1+n)%n;
39         else id = (i+c2-2+n)%n;
40         if(id == 0) id = n;
41         ans[id] = i;
42     }
43     for(int i = 1;i <= n;i++) printf("%d ",ans[i]);
44     printf("\n");
45 }
46 
47 int main(){
48     while(scanf("%d %d",&n,&q) != EOF){
49         solve();
50     }
51     return 0;
52 }
View Code

 

cf 348div2 e E - Little Artem and Time Machine

第 t 秒的时候,给集合加入 一个数 

第 t 秒的时候,从集合中删除一个数

询问 某一秒,某一个数的个数

可以用树状数组,再离散化一下

map<int,int> c[maxn]

的空间 是 这样 的 c[maxn][int] 的,调了一会儿..

题解有说 是 裸的可持久化treap......不会....好菜啊..

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<map>
 6 using namespace std;
 7 
 8 const int maxn = 1e6+5;
 9 const int N = 1e9+5;
10 map<int,int> c[maxn];
11 map<int,int> a;
12 int n;
13 
14 int lowbit(int x){return x & (-x);}
15 
16 void Update(int x,int y,int d){
17     while(x < N){
18         c[y][x] += d;
19         x += lowbit(x);
20     }
21 }
22 
23 int sum(int x,int y){
24     int res = 0;
25     while(x){
26         res += c[y][x];
27         x -= lowbit(x);
28     }
29     return res;
30 }
31 
32 void solve(){
33     int cmd,t,x;
34     int tot = 0;
35     for(int i = 1;i < maxn;i++) c[i].clear();
36     for(int i = 1;i <= n;i++){
37         scanf("%d %d %d",&cmd,&t,&x);
38         if(!a[x]) a[x] = ++tot;
39         if(cmd == 1) Update(t,a[x],1);
40         if(cmd == 2) Update(t,a[x],-1);
41         if(cmd == 3){
42             int ans = sum(t,a[x]);
43             printf("%d\n",ans);
44         }
45     }
46 }
47 
48 int main(){
49     while(scanf("%d",&n) != EOF){
50         solve();
51     }
52     return 0;
53 }
View Code

 

7.7

发呆..

7.8

傻逼果然就是傻逼..

 

cf 361 div2 a A - Mike and Cellphone

很简单的题..依然wa了无数发.

给出一个人按键盘的方式,问摁出来的电话号码是不是唯一的

枚举摁的起点,按照给出的按键方式去模拟..

因为自己开的数组小了,在本地跑的数据是对的,可是在cf上就不对了..不止一次犯过这种错误了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int x[10] = {4,1,1,1,2,2,2,3,3,3};
 8 int y[10] = {2,1,2,3,1,2,3,1,2,3};
 9 int g[25][25],n;
10 char s[15];
11 
12 int ok(int u,int v){
13     for(int i = 2;i <= n;i++){
14         int xx = x[s[i]-'0']-x[s[i-1]-'0'];
15         int yy = y[s[i]-'0']-y[s[i-1]-'0'];
16         int nx = u+xx;
17         int ny = v+yy;
18         if(g[nx][ny] == 0) return 0;
19         u = nx;v=ny;
20     }
21     return 1;
22 }
23 
24 void solve(){
25     if(n == 1){
26         puts("NO");
27         return;
28     }
29     memset(g,0,sizeof(g));
30     for(int i = 1;i <= 3;i++){
31         for(int j = 1;j <= 3;j++) g[i][j] = 1;
32     }
33     g[4][2] = 1;
34     int px = x[s[1]-'0'];
35     int py = y[s[1]-'0'];
36     int cnt = 0;
37     for(int i = 1;i <= 3;i++){
38         for(int j = 1;j <= 3;j++){
39             if(ok(i,j)){
40                 cnt++;
41             }
42         }
43     }
44     if(ok(4,2)){
45         cnt++;
46     }
47     if(cnt > 1) puts("NO");
48     else puts("YES");
49 }
50 
51 int main(){
52     while(scanf("%d",&n) != EOF){
53         scanf("%s",s+1);
54         solve();
55     }
56     return 0;
57 }
View Code

 

cf 361 div2b B - Mike and Shortcuts

bfs

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 
 8 const int maxn = 2e5+5;
 9 int a[maxn],d[maxn],vis[maxn];
10 int n;
11 const int INF = (1<<30)-1;
12 
13 void bfs(int st){
14     for(int i = 1;i <= n;i++) d[i] = INF;
15     d[st] = 0;
16     queue<int> q;
17     q.push(st);
18     int u,v;
19     while(!q.empty()){
20         u = q.front();q.pop();
21         v = u+1;
22         if(v <= n && d[v] > d[u]+1){
23             q.push(v);
24             d[v] = d[u]+1;
25         }
26         v = u-1;
27         if(v >= 1 && d[v] > d[u]+1){
28             q.push(v);
29             d[v] = d[u]+1;
30         }
31         v = a[u];    
32         if(d[v] > d[u]+1){
33             q.push(v);
34             d[v] = d[u]+1;
35         }
36     }
37 }
38 
39 int main(){
40     while(scanf("%d",&n) != EOF){
41         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
42         bfs(1);
43         for(int i = 1;i <= n;i++) printf("%d ",d[i]);
44         printf("\n");
45     }
46     return 0;
47 }
View Code

 

cf 361 div2c C - Mike and Chocolate Thieves

二分

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int maxn = 1e6+5;
 9 LL p[maxn],m;
10 
11 long long ok(LL x){
12     LL cnt = 0LL;
13     for(int i = 2;i < maxn;i++){
14         LL tmp = x/p[i];
15         cnt += tmp;
16     }
17     //printf("--------------------x = %I64d cnt = %I64d\n",x,cnt);
18     return cnt;
19 }
20 
21 void solve(){
22     LL lb = 0,ub = 1e18,mid,ans = 0LL;
23     for(int i = 0;i <= 100;i++){
24         mid = (lb+ub)/2LL;
25         if(ok(mid) >= m){
26             ub = mid-1;
27             ans = mid;
28             //printf("-------------mid mid = %I64d\n",mid);
29         }
30         else lb = mid+1;
31         //printf("lb = %I64d ub = %I64d mid = %I64d ans = %I64d\n",lb,ub,mid,ans);
32     }
33     if(ok(ans) == m) printf("%I64d\n",ans);
34     else puts("-1");
35 }
36 
37 int main(){
38     for(int i = 1;i < maxn;i++) p[i] = 1LL*i*i*i;
39     cin >> m;
40     solve();    
41     return 0;
42 }
View Code

 

7.10

cf 361 div2 d D - Friends and Subsequences

不会二分..

又好多天没做leetcode了...要gg..

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <map>
 5 #include <vector>
 6 #include <algorithm>
 7 using namespace std;
 8 typedef long long LL;
 9 const int maxn = 2e5+10;
10 int n,a[maxn],b[maxn],mx[maxn][55],mn[maxn][55];
11 
12 void RMQ_init(){
13     for(int i = 0;i < n;i++) mx[i][0] = a[i];
14     for(int i = 0;i < n;i++) mn[i][0] = b[i];
15     for(int j = 1;(1<<j) <= n;j++){
16         for(int i = 0;i + (1<<j) - 1 < n;i++){
17             mx[i][j] = max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
18             mn[i][j] = min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
19         }
20     }
21 }
22 
23 int RMQ_mx(int L,int R){
24     int k = 0;
25     while((1<<(k+1)) <= R-L+1) k++;
26     return max(mx[L][k],mx[R-(1<<k)+1][k]);
27 }
28 
29 int RMQ_mn(int L,int R){
30     int k = 0;
31     while((1<<(k+1)) <= R-L+1) k++;
32     return min(mn[L][k],mn[R-(1<<k)+1][k]);
33 }
34 
35 void solve(){
36     RMQ_init();
37     LL res = 0LL;
38     int lb,ub,mid,c1,c2;
39     for(int i = 0;i < n;i++){
40         lb = i;ub = n;
41         for(int k = 1;k <= 100;k++){
42             mid = lb+(ub-lb)/2;
43             if(RMQ_mx(i,mid) >= RMQ_mn(i,mid)) ub = mid;
44             else lb = mid+1;
45         }
46         c1 = ub;
47         lb = i;ub = n;
48         for(int k = 1;k <= 100;k++){
49             mid = lb+(ub-lb)/2;
50             if(RMQ_mx(i,mid) > RMQ_mn(i,mid)) ub = mid;
51             else lb = mid+1;
52         }
53         c2 = ub;
54         res += 1LL*(c2-c1);
55         //printf("c1 = %d c2 = %d\n",c1,c2);
56     }
57     printf("%I64d\n",res);
58 }
59 
60 int main(){
61     while(scanf("%d",&n) != EOF){
62         for(int i = 0;i < n;i++) scanf("%d",&a[i]);
63         for(int i = 0;i < n;i++) scanf("%d",&b[i]);
64         solve();
65     }
66     return 0;
67 }
View Code

 

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值