[USACO18]Out of sort P 解题报告
传送门:戳我
不难发现,冒泡的时候,不是最大的数字一定会往前走一格,最大的数字一定沉底到最右。
那么答案就是某个数字最右的比他小的数字的值的和。
注意离散化
又是一篇捞的博客
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 260817 using namespace std; inline void read(int &x){ x=0;int f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} x*=f; } int N; inline int lowbit(int i){ return i&(-i); } long long tree[maxn<<1]; long long tim[maxn]; inline long long query(int p){ long long ans=0; for(int i=p;i>0;i-=lowbit(i)) ans+=tree[i]; return ans; } inline void update(int p,int x){ for(int i=p;i<=N;i+=lowbit(i)) tree[i]+=x; } int a[maxn],b[maxn],p[maxn],hash[maxn]; int main(){ // freopen("sort.in","r",stdin); // freopen("sort.out","w",stdout); read(N); for(int i=1;i<=N;i++) { read(a[i]); b[i]=a[i]; } sort(b+1,b+1+N); for(int i=1;i<=N;i++) { int pos=lower_bound(b+1,b+1+N,a[i])-b; int delt=hash[pos]; hash[pos]++; p[delt+pos]=i; } int r=0; // for(int i=1;i<=N;i++) // cout<<p[i]<<" "; // cout<<endl; long long ans=0; for(int i=1;i<=N;i++) { r=max(r,p[i]); tim[i]=max(1,r-i); //cout<<tim[i]<<" "; } for(int i=1;i<=N;i++) ans+=max(tim[i],tim[i-1]); printf("%lld",ans); }