P10589 楼兰图腾
题目描述
在完成了分配任务之后,西部 314 来到了楼兰古城的西部。相传很久以前这片土地上(比楼兰古城还早)生活着两个部落,一个部落崇拜尖刀(V),一个部落崇拜铁锹(∧),他们分别用 V 和 ∧ 的形状来代表各自部落的图腾。
西部 314 在楼兰古城的下面发现了一幅巨大的壁画,壁画上被标记出了 nnn 个点,经测量发现这 nnn 个点的水平位置和竖直位置是两两不同的。西部 314 认为这幅壁画所包含的信息与这 nnn 个点的相对位置有关,因此不妨设坐标分别为 (1,y1),(2,y2),⋯ ,(n,yn)(1,y_1),(2,y_2),\cdots,(n,y_n)(1,y1),(2,y2),⋯,(n,yn),其中 y1∼yny_1\sim y_ny1∼yn 是 111 到 nnn 的一个排列。

如图,图中的 y1=1y_1=1y1=1,y2=5y_2=5y2=5,y3=3y_3=3y3=3,y4=2y_4=2y4=2,y5=4y_5=4y5=4。
西部 314 打算研究这幅壁画中包含着多少个图腾,其中 V 图腾的定义如下(注意:图腾的形式只和这三个纵坐标的相对大小排列顺序有关)1≤i<j<k≤n1\le i<j<k\le n1≤i<j<k≤n 且 yi>yjy_i>y_jyi>yj, yj<yky_j<y_kyj<yk;
而崇拜 ∧ 的部落的图腾被定义为 1≤i<j<k≤n1\le i<j<k\le n1≤i<j<k≤n 且 yi<yjy_i<y_jyi<yj,yj>yky_j>y_kyj>yk;
西部 314 想知道,这 nnn 个点中两个部落图腾的数目。因此,你需要编写一个程序来求出 V 的个数和 ∧ 的个数。
输入格式
第一行一个正整数 nnn;
第二行是 nnn 个正整数,分别代表 y1,y2,⋯ ,yny_1,y_2,\cdots,y_ny1,y2,⋯,yn。
输出格式
输出两个数,中间用空格隔开,依次为 V 的个数和 ∧ 的个数
输入输出样例 #1
输入 #1
5
1 5 3 2 4
输出 #1
3 4
说明/提示
数据范围约定
- 对于 10%10\%10% 的数据 n≤600n\le 600n≤600;
- 对于 40%40\%40% 的数据 n≤5000n\le 5000n≤5000;
- 对于 100%100\%100% 的数据 n≤200000n\le 200000n≤200000,答案不超过 263−12^{63} - 1263−1。
C++实现
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[200001],ans1,ans2;
int L[200001][2],R[200001][2],t[200001];//数组
int lowbit(int x){//模板
return x&-x;
}void add(int x,int y){
while(x<=n){
t[x]+=y;
x=x+lowbit(x);
}return ;
}int ask(int x){
int cnt=0;
while(x){
cnt+=t[x];
x=x-lowbit(x);
}return cnt;
}signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}for(int i=1;i<=n;i++){//统计数量
L[i][0]=i-1-ask(a[i]);
L[i][1]=ask(a[i]-1);
add(a[i],1);
}memset(t,0,sizeof(t));
for(int i=n;i>=1;i--){//统计数量
R[i][0]=n-i-ask(a[i]);
R[i][1]=ask(a[i]-1);
add(a[i],1);
}for(int i=1;i<=n;i++){//处理答案
ans1+=L[i][0]*R[i][0];
ans2+=L[i][1]*R[i][1];
}cout<<ans1<<" "<<ans2;
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
用C++实现信奥题 P10589 楼兰图腾&spm=1001.2101.3001.5002&articleId=163229600&d=1&t=3&u=30a9eb264fcf44baa1d4db5869f769f9)
353

被折叠的 条评论
为什么被折叠?



