同学想着用线段树写,但是提交后只过了1/10的样例,百思不得其解,遂对拍找问题,发现理解题意有问题emmmm(就离谱)。
黑色为已删除,红色为当前删除,当删除f时,我们想的是将c+e的值输出,因为c和e都在f的一侧,但是别人通过的代码输出的是c或e当中较大的值,然后就没有然后了。
#include<bits/stdc++.h> using namespace std; const int MAX=5e4+5; bool st[MAX]; int sum,w[MAX]={0,1,5,7,1,9,1},idx[MAX],p[MAX],cnt[MAX]; int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } void unite(int a, int b) { a = find(a), b = find(b); p[a] = b; cnt[b] += cnt[a]; sum = max(sum, cnt[b]); } //----------------------- int tree[MAX*4],ress[MAX]; void pushup(int rt) { tree[rt]=tree[rt<<1]+tree[rt<<1|1]; } void build(int l,int r,int rt) { if(l==r) { tree[rt]=w[l]; return ; } int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } int query(int L,int R,int l,int r,int rt) { if(L>R)return 0; if(L<=l&&r<=R)return tree[rt]; int mid=(l+r)>>1; int ans=0; if(L<=mid)ans+=query(L,R,l,mid,rt<<1); if(R>mid)ans+=query(L,R,mid+1,r,rt<<1|1); return ans; } void update(int L,int R,int l,int r,int rt) { if(l==r) { tree[rt]=0; return ; } int mid=(l+r)>>1; if(L<=mid)update(L,R,l,mid,rt<<1); else update(L,R,mid+1,r,rt<<1|1); pushup(rt); } int main() { int idx[8]={0,1,2,3,4,5,6}; int n=6; do { for(int i=1;i<=n;i++) p[i]=i,cnt[i]=0,st[i]=false;//,tree[i]=0; sum=0; memset(tree,0,sizeof(tree)); vector<int>res; res.clear(); res.push_back(0); for(int i=n;i>=2;i--) { int x=idx[i]; st[x]=true; cnt[x]=w[x]; sum=max(sum,cnt[x]); if(st[x - 1]) unite(x-1,x); if(st[x + 1]) unite(x+1,x); res.push_back(sum); } // for(int i=0;i<n;i++) cout<<res[i]<<endl; // printf("%d\n",res[i]); build(1,n,1); for(int i=1;i<=n;i++) { // cout<<max(query(1,idx[i]-1,1,n,1),query(idx[i]+1,n,1,n,1))<<endl; ress[n-i]=max(query(1,idx[i]-1,1,n,1),query(idx[i]+1,n,1,n,1)); // printf("%d\n",ress[n-i]); update(idx[i],idx[i],1,n,1); } // for(int i=0;i<n;i++) cout<<res[i]<<endl; // printf("%d\n",ress[i]); for(int i=0;i<n;i++) { bool flag=true; if(ress[i]!=res[i]) flag=false; if(flag==false) { for(int i=1;i<=n;i++) printf("%d ",idx[i]); printf("\n"); for(int i=0;i<n;i++) printf("%d ",res[i]); printf("\n"); for(int i=0;i<n;i++) printf("%d ",ress[i]); printf("\n"); getchar(); break; } } }while (next_permutation(idx+1,idx+7));// 下个全排列 return 0; }