题目大意就是给一个初始数组,每次删除一个点,问你剩下的连续的那些点中,最大的和是多少
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&&&\n",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 }
///并查集
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\n",ans[i]); 84 return 0; 85 }
原文地址:https://www.cnblogs.com/DreamKill/p/9427830.html
时间: 2024-10-31 04:46:28