【BZOJ4504&&Hihocoder1046】K个串(主席树,堆)
题意:一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次)询问第k大的和是多少
1 <= n <= 100000, 1 <= k <= 200000, 0 <= a[i]<= 10^9
思路:类似于超级钢琴的思路
对于每一个右端点建立一棵主席树维护左端点的最大值
对于a[i]它对[last[a[i]]+1,i]有a[i]的贡献
再维护一个堆维护全局最大值
删除的时候就找到最大值的位置赋值成最小值
C++ STL 不会用 好烦
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<ctime> 6 #include<cmath> 7 #include<algorithm> 8 #include<iomanip> 9 #include<vector> 10 #include<map> 11 #include<set> 12 #include<bitset> 13 #include<queue> 14 #include<stack> 15 using namespace std; 16 typedef long long ll; 17 typedef unsigned int uint; 18 typedef unsigned long long ull; 19 typedef pair<int,int> PII; 20 typedef vector<int> VI; 21 #define fi first 22 #define se second 23 #define MP make_pair 24 #define N 21000000 25 #define M 110000 26 #define eps 1e-8 27 #define pi acos(-1) 28 #define oo 1e18 29 #define MOD 10007 30 31 struct node 32 { 33 ll v; 34 int id; 35 node() 36 { 37 } 38 node(ll V,int P) 39 { 40 v=V; id=P; 41 } 42 friend bool operator <(node x,node y) 43 { 44 return x.v<y.v; 45 } 46 }; 47 48 struct tree 49 { 50 int l,r; 51 ll a,s; 52 }t[N]; 53 54 priority_queue<node>q; 55 map<int,int>last; 56 int a[M],root[M],n,cnt; 57 58 void pushup(int p) 59 { 60 t[p].s=0; 61 if(!t[p].r) t[p].s=t[t[p].l].s; 62 else if(!t[p].l) t[p].s=t[t[p].r].s; 63 else t[p].s=max(t[t[p].l].s,t[t[p].r].s); 64 t[p].s+=t[p].a; 65 } 66 67 void update(int l,int r,int x,int y,int v,int &r1,int r2) 68 { 69 r1=++cnt; 70 t[r1]=t[r2]; 71 if(x<=l&&r<=y) 72 { 73 t[r1].a+=v; 74 pushup(r1); 75 return; 76 } 77 int mid=(l+r)>>1; 78 if(x<=mid) update(l,mid,x,y,v,t[r1].l,t[r2].l); 79 if(y>mid) update(mid+1,r,x,y,v,t[r1].r,t[r2].r); 80 pushup(r1); 81 } 82 83 void del(int l,int r,int &p) 84 { 85 int x=p; 86 p=++cnt; 87 t[cnt]=t[x]; 88 if(l==r) 89 { 90 t[p].a=-oo; 91 pushup(p); 92 return; 93 } 94 int mid=(l+r)>>1; 95 if(!t[p].r) del(l,mid,t[p].l); 96 else if(!t[p].l) del(mid+1,r,t[p].r); 97 else 98 { 99 if(t[t[p].l].s>=t[t[p].r].s) del(l,mid,t[p].l); 100 else del(mid+1,r,t[p].r); 101 } 102 pushup(p); 103 } 104 105 106 int main() 107 { 108 //freopen("bzoj4504.in","r",stdin); 109 //freopen("bzoj4504.out","w",stdout); 110 int k; 111 scanf("%d%d",&n,&k); 112 cnt=0; 113 for(int i=1;i<=n;i++) 114 { 115 scanf("%d",&a[i]); 116 update(1,n,i,i,0,root[i],root[i-1]); 117 update(1,n,last[a[i]]+1,i,a[i],root[i],root[i]); 118 last[a[i]]=i; 119 q.push(node(t[root[i]].s,i)); 120 } 121 for(int i=1;i<k;i++) 122 { 123 int x=q.top().id; 124 q.pop(); 125 del(1,n,root[x]); 126 q.push(node(t[root[x]].s,x)); 127 } 128 printf("%lld\n",q.top().v); 129 return 0; 130 } 131 132
null