C. Destroying Array 并查集/线段树 Intel Code Challenge Elimination Round (Div. 1 + Div. 2, combined)

  题目大意就是给一个初始数组,每次删除一个点,问你剩下的连续的那些点中,最大的和是多少

  2种做法

   第一种是离线并查集  (这里是不会用那个res[]数组,将子的权值挪给父亲那里.

   第二种是线段树区间合并。(练手

   ///线段树

   

  1 #include <algorithm>
  2 #include <stack>
  3 #include <istream>
  4 #include <stdio.h>
  5 #include <map>
  6 #include <math.h>
  7 #include <vector>
  8 #include <iostream>
  9 #include <queue>
 10 #include <string.h>
 11 #include <set>
 12 #include <cstdio>
 13 #define FR(i,n) for(int i=0;i<n;i++)
 14 #define MAX 2005
 15 #define mkp pair <int,int>
 16 using namespace std;
 17 //#pragma comment(linker, "/STACK:10240000000,10240000000")
 18 const int maxn = 1e5+50;
 19 typedef long long ll;
 20 const int  inf = 0x3fffff;
 21 void read(ll  &x) {
 22     char ch; bool flag = 0;
 23     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
 24     for (x = 0; isdigit(ch); x = (x << 1) + (x << 3) + ch - 48, ch = getchar());
 25     x *= 1 - 2 * flag;
 26 }
 27 int n;
 28 ll val[maxn];
 29 struct tree {
 30     //int id;
 31     int l, r;
 32     long long  ll, rr;
 33     long long  maxx;
 34     int len;
 35     bool flag;
 36 }Tree[maxn<<3];
 37 
 38 ll query[maxn];
 39 
 40 
 41 void build(int l, int r, int id)
 42 {
 43     Tree[id].flag = true;
 44     Tree[id].l = l;
 45     Tree[id].r = r;
 46     Tree[id].len=r-l+1;
 47     if (l == r)
 48     {
 49         Tree[id].maxx = Tree[id].ll=Tree[id].rr=val[l];
 50         return;
 51     }
 52     int mid = (l + r) / 2;
 53     build(mid + 1, r, 2 * id + 1);
 54     build(l, mid, 2 * id);
 55     Tree[id].maxx = Tree[id * 2].maxx + Tree[id * 2 + 1].maxx;
 56     Tree[id].ll = Tree[id].rr = Tree[id].maxx;
 57 }
 58 
 59 
 60 
 61 void pushup(int id)
 62 {
 63     Tree[id].ll = Tree[id * 2].ll;
 64     if (Tree[id * 2].flag)Tree[id].ll += Tree[id * 2 + 1].ll;
 65 
 66     Tree[id].rr = Tree[id * 2 + 1].rr;
 67     if (Tree[id * 2 + 1].flag)Tree[id].rr += Tree[id * 2].rr;
 68     Tree[id].maxx = max(Tree[id * 2].maxx,Tree[id * 2 + 1].maxx);
 69     Tree[id].maxx = max(Tree[id].maxx, Tree[id * 2+1].ll + Tree[id * 2 ].rr);
 70     if (!Tree[id * 2].flag || !Tree[id * 2 + 1].flag)Tree[id].flag = 0;
 71 }
 72 void repair(int id, int pos)
 73 {
 74    // cout<<id<<endl;
 75     if (Tree[id].l == pos && Tree[id].r == pos)
 76     {
 77         //printf("%d&&&
",Tree[id].l);
 78         Tree[id].flag = 0;
 79         Tree[id].ll = Tree[id].rr =Tree[id].maxx =0;
 80     }
 81     else
 82     {
 83         int mid = (Tree[id].l + Tree[id].r) / 2;
 84         if (pos > mid) {
 85             repair(id * 2 + 1, pos);
 86         }
 87         else {
 88             repair(id * 2, pos);
 89         }
 90         pushup(id);
 91     }
 92 }
 93 int main() {
 94     cin>>n;
 95     for (int i = 1; i <= n; i++)read(val[i]);
 96     for (int i = 1; i <= n; i++)read(query[i]);
 97 
 98     build(1, n, 1);
 99     for (int i = 1; i  <= n; i++ )
100     {
101         repair(1, query[i]);
102         cout << Tree[1].maxx << endl;
103     }
104     return 0;
105 }
View Code

 ///并查集

 1 #include <algorithm>
 2 #include <stack>
 3 #include <istream>
 4 #include <stdio.h>
 5 #include <map>
 6 #include <math.h>
 7 #include <vector>
 8 #include <iostream>
 9 #include <queue>
10 #include <string.h>
11 #include <set>
12 #include <cstdio>
13 #define FR(i,n) for(int i=0;i<n;i++)
14 #define MAX 2005
15 #define mkp pair <int,int>
16 using namespace std;
17 //#pragma comment(linker, "/STACK:10240000000,10240000000")
18 const int maxn = 1e6+4;
19 typedef long long ll;
20 const int  inf = 0x3fffff;
21 void read(ll  &x) {
22     char ch; bool flag = 0;
23     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
24     for (x = 0; isdigit(ch); x = (x << 1) + (x << 3) + ch - 48, ch = getchar());
25     x *= 1 - 2 * flag;
26 }
27 
28 
29 ll res[maxn],arr[maxn],fa[maxn];
30 ll pos[maxn];
31 bool vis[maxn];
32 ll ans[maxn];
33 
34 
35 ll fin(ll x)
36 {
37     if(x==fa[x])return x;
38     else {
39         return fa[x]=fin(fa[x]);
40     }
41 }
42 
43 void unite(ll x,ll y)
44 {
45     x=fin(x),y=fin(y);
46     if(x==y)return ;
47     else {
48         fa[y]=x;
49         res[x]+=res[y];
50     }
51 }
52 
53 int main() {
54     ll n;
55     read(n);
56     for(int i=1;i<=n;i++)read(arr[i]);
57     for(int i=1;i<=n;i++)
58     {
59         read(pos[i]);
60         res[pos[i]]=arr[pos[i]];
61         fa[i]=i;
62         vis[i]=1;
63     }
64     for(int i=n;i>=2;i--)
65     {
66         ll tmp =pos[i];
67         if(pos[i]!=n)
68         {
69             if(!vis[tmp+1])
70             {
71                 unite(tmp,tmp+1);
72             }
73 
74         }
75             if(tmp>=2&&!vis[tmp-1])
76             {
77                 unite(tmp,tmp-1);
78             }
79         ll temp = res[tmp];
80         ans[i]=max(ans[i+1],temp);
81         vis[tmp]=false;
82     }
83     for(int i=2;i<=n+1;i++)printf("%lld
",ans[i]);
84     return 0;
85 }
View Code
我身后空无一人,我怎敢倒下
原文地址:https://www.cnblogs.com/DreamKill/p/9427830.html