1 条题解
-
0
思维题,挺不错的一个树状数组题,代码不长,
甚至不需要排序考场上一看到这题其实窝是懵的,接下来,输出的方式给了我一点提示
看到
对于每一个 j=0,1,…,N−1,用一行输出 Farmer John 头发的不良度我们想到了倒推如何倒推呢?我们考虑FJ去种头发而不是剃头发(大雾)
为了便于理解,我们
强行加一个时间,我们假设每一秒fj的头发都会长1微米,然后第 个头发在长度到达 的时候就不会继续长了于是,我们考虑每一秒新增的逆序对数
发现第 秒新增的逆序对数就是每个长度为 的头发的前面在第 秒时还在长的头发数量
发现,这句话我们换一种方式说就是第 个头发对答案的贡献从第 秒开始,并且贡献的大小为满足 的 的个数
发现这东西就是个逆序对,树状数组维护一下就好啦~
code:
#include<bits/stdc++.h> #define MAXN 100100 #define int long long//别忘记longlong哦 using namespace std; int n,a[MAXN]; class tarray { private: int tree[MAXN]; int lowbit(int x){return x&(-x);} public: void update(int x,int y){while(x<=n){tree[x]+=y;x+=lowbit(x);}} int query(int x){int ret=0;while(x){ret+=tree[x];x-=lowbit(x);}return ret;} }t;//树状数组 int s[MAXN],ans; signed main() { freopen("haircut.in","r",stdin); freopen("haircut.out","w",stdout); scanf("%lld",&n); for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]++; for(int i=1;i<=n;i++)//统计逆序对 { int x=n-a[i]+2; s[a[i]]+=t.query(x-1); t.update(x,1); } printf("0");//第0秒的答案 for(int i=2;i<=n;i++)//统计答案 { ans+=s[i-1]; printf("\n%lld",ans); } return 0; }后记:这个赛季usaco就卡在G组了,没能晋级P组,下赛季加油咯
- 1
信息
- ID
- 6870
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 3
- 上传者