题意:给你两个栈,给你一开始的分配。每次移动一个栈顶的元素放到另一个栈顶花费1。
并且你可以删除一个栈顶元素,花费0。
问你从大到小删除所有数的花费。
n1+n2<=1e5。
标程:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long ll; 5 const int N=100005; 6 int n1,n2,n,a[N],bit[N],b[N]; 7 ll ans; 8 9 int lowbit(int x){return x&(-x);} 10 11 int qry(int x){int res=0;while (x) res+=bit[x],x-=lowbit(x);return res;} 12 13 void del(int x) {while (x<=n) bit[x]--,x+=lowbit(x);} 14 15 bool cmp(int A,int B) {return a[A]>a[B];} 16 17 int main() 18 { 19 scanf("%d%d",&n1,&n2); 20 for (int i=n1;i>=1;i--) scanf("%d",&a[i]); 21 for (int i=n1+1;i<=n1+n2;i++) scanf("%d",&a[i]); 22 n=n1+n2; 23 for (int i=1;i<=n;i++) b[i]=i,bit[i]=lowbit(i); 24 sort(b+1,b+n+1,cmp); 25 for (int i=1;i<=n;i++) 26 { 27 if (b[i]<=n1) ans+=qry(n1)-qry(b[i]);//在第一段中 28 else ans+=qry(b[i])-qry(n1)-1;//在第二段中 29 n1=b[i]-1;del(b[i]); 30 } 31 printf("%lld ",ans); 32 return 0; 33 }
题解:树状数组+栈对顶
将两个栈的顶部连在一起变成一个数组。那么从当前最大移动到次大的路径就是中间的距离(元素个数)。删掉一个最大元素则经过其的所有路径都-1,用树状数组维护距离,当前点-1即可。
小技巧:统计距离的话,初始化把树状数组每一位的值设成lowbit(i)。
固定n1位第一栈的顶,方便讨论,要讨论b[i]和n1的左右位置关系。
水题都切不动了啊,你还有什么用。加油!多做题多熟悉技巧!