打卡信奥刷题(3010)用C++实现信奥题 P6278 [USACO20OPEN] Haircut G
P6278 [USACO20OPEN] Haircut G
题目描述
Farmer John 由于对整理他难以整平的头发感到疲惫,于是决定去理发。他有一排 NNN 缕头发,第 iii 缕头发初始时长度为 AiA_iAi 微米(0≤Ai≤N0\le A_i\le N0≤Ai≤N)。理想情况下,他想要他的头发在长度上单调不降,所以他定义他的头发的“不良度”为逆序对的数量:满足 i<ji < ji<j 及 Ai>AjA_i > A_jAi>Aj 的二元对 (i,j)(i,j)(i,j)。
对于每一个 j=0,1,…,N−1j=0,1,\ldots,N-1j=0,1,…,N−1,Farmer John 想要知道他所有长度大于 jjj 的头发的长度均减少到 jjj 时他的头发的不良度。
(有趣的事实:人类平均确实有大约 10510^5105 根头发!)
输入格式
输入的第一行包含 NNN。
第二行包含 A1,A2,…,ANA_1,A_2,\ldots,A_NA1,A2,…,AN。
输出格式
对于每一个 j=0,1,…,N−1j=0,1,\ldots,N-1j=0,1,…,N−1,用一行输出 Farmer John 头发的不良度。
注意这个问题涉及到的整数大小可能需要使用 646464 位整数型存储(例如,C/C++ 中的“long long”)。
输入输出样例 #1
输入 #1
5
5 2 3 3 0
输出 #1
0
4
4
5
7
说明/提示
样例解释:
输出的第四行描述了 Farmer John 的头发长度减少到 333 时的逆序对数量。
A=[3,2,3,3,0]A=[3,2,3,3,0]A=[3,2,3,3,0] 有五个逆序对:A1>A2, A1>A5, A2>A5, A3>A5,A_1>A_2,\,A_1>A_5,\,A_2>A_5,\,A_3>A_5,A1>A2,A1>A5,A2>A5,A3>A5, 和 A4>A5A_4>A_5A4>A5。
对于 100%100\%100% 的数据,1≤N≤1051\le N\le 10^51≤N≤105。
共 131313 个测试点,其中 111 为样例,其余性质如下:
测试点 222 满足 N≤100N\le 100N≤100。
测试点 3∼53\sim 53∼5 满足 N≤5000N\le 5000N≤5000。
测试点 6∼136\sim 136∼13 没有额外限制。
出题人:Dhruv Rohatgi
C++实现
#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()
{
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;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)