Scx117
只一眼,便辽阔了时间。

题意:给你两个栈,给你一开始的分配。每次移动一个栈顶的元素放到另一个栈顶花费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\n",ans);
32     return 0;
33 } 

 

题解:树状数组+栈对顶

将两个栈的顶部连在一起变成一个数组。那么从当前最大移动到次大的路径就是中间的距离(元素个数)。删掉一个最大元素则经过其的所有路径都-1,用树状数组维护距离,当前点-1即可。

 

小技巧:统计距离的话,初始化把树状数组每一位的值设成lowbit(i)。

固定n1位第一栈的顶,方便讨论,要讨论b[i]和n1的左右位置关系。

水题都切不动了啊,你还有什么用。加油!多做题多熟悉技巧!

posted on 2018-05-26 23:03  Scx117  阅读(156)  评论(0编辑  收藏  举报