楼兰图腾(权值线段树)
在完成了分配任務(wù)之后,西部314來到了樓蘭古城的西部。
相傳很久以前這片土地上(比樓蘭古城還早)生活著兩個(gè)部落,一個(gè)部落崇拜尖刀(‘V’),一個(gè)部落崇拜鐵鍬(‘∧’),他們分別用V和∧的形狀來代表各自部落的圖騰。
西部314在樓蘭古城的下面發(fā)現(xiàn)了一幅巨大的壁畫,壁畫上被標(biāo)記出了N個(gè)點(diǎn),經(jīng)測量發(fā)現(xiàn)這N個(gè)點(diǎn)的水平位置和豎直位置是兩兩不同的。
西部314認(rèn)為這幅壁畫所包含的信息與這N個(gè)點(diǎn)的相對位置有關(guān),因此不妨設(shè)坐標(biāo)分別為(1,y1),(2,y2),…,(n,yn)(1,y1),(2,y2),…,(n,yn),其中y1y1~ynyn是1到n的一個(gè)排列。
西部314打算研究這幅壁畫中包含著多少個(gè)圖騰。
如果三個(gè)點(diǎn)(i,yi),(j,yj),(k,yk)(i,yi),(j,yj),(k,yk)滿足1≤i<j<k≤n且yi>yj,yj<yk1≤i<j<k≤n且yi>yj,yj<yk,則稱這三個(gè)點(diǎn)構(gòu)成V圖騰;
如果三個(gè)點(diǎn)(i,yi),(j,yj),(k,yk)(i,yi),(j,yj),(k,yk)滿足1≤i<j<k≤n且yi<yj,yj>yk1≤i<j<k≤n且yi<yj,yj>yk,則稱這三個(gè)點(diǎn)構(gòu)成∧圖騰;
西部314想知道,這n個(gè)點(diǎn)中兩個(gè)部落圖騰的數(shù)目。
因此,你需要編寫一個(gè)程序來求出V的個(gè)數(shù)和∧的個(gè)數(shù)。
輸入格式
第一行一個(gè)數(shù)n。
第二行是n個(gè)數(shù),分別代表y1,y2,…,yny1,y2,…,yn。
輸出格式
兩個(gè)數(shù),中間用空格隔開,依次為V的個(gè)數(shù)和∧的個(gè)數(shù)。
數(shù)據(jù)范圍
對于所有數(shù)據(jù),n≤200000n≤200000,且輸出答案不會超過int64。
輸入樣例:
5 1 5 3 2 4輸出樣例:
3 4不明白為什么不需要離散化
代碼: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<set> #include<map> #include<vector> #include<cmath>
const int maxn=2e5+5; typedef long long ll; using namespace std; struct node { int l,r; int num; }tree[maxn<<2]; vector<int>v; int a[maxn];
void pushup(int m) { tree[m].num=(tree[m<<1].num+tree[m<<1|1].num); }
void build(int m,int l,int r) { tree[m].l=l; tree[m].r=r; tree[m].num=0; if(l==r) { return ; } int mid=(tree[m].l+tree[m].r)>>1; build(m<<1,l,mid); build(m<<1|1,mid+1,r); } void update(int m,int pos,int val) { if(tree[m].l==tree[m].r) { tree[m].num+=val; return; } int mid=(tree[m].l+tree[m].r)>>1; if(pos<=mid) { update(m<<1,pos,val); } else { update(m<<1|1,pos,val); } pushup(m); } int query(int m,int l,int r) { if(tree[m].l==l&&tree[m].r==r) { return tree[m].num; } int mid=(tree[m].l+tree[m].r)>>1; if(r<=mid) { return query(m<<1,l,r); } else if(l>mid) { return query(m<<1|1,l,r); } else { return query(m<<1,l,mid)+query(m<<1|1,mid+1,r); } } ll minl[maxn],minr[maxn],maxl[maxn],maxr[maxn]; int main() {
int n; cin>>n; for(int t=1;t<=n;t++) { scanf("%d",&a[t]); } build(1,0,n+1); for(int t=1;t<=n;t++) { minl[t]=query(1,0,a[t]-1); maxl[t]=query(1,a[t]+1,n+1); update(1,a[t],1); } build(1,0,n+1); for(int t=n;t>=1;t--) { minr[t]=query(1,0,a[t]-1); maxr[t]=query(1,a[t]+1,n+1); update(1,a[t],1); } ll ans1=0,ans2=0; for(int t=1;t<=n;t++) { ans1+=maxl[t]*maxr[t]; ans2+=minl[t]*minr[t]; } printf("%lld %lld\n",ans1,ans2);
system("pause"); return 0; }
轉(zhuǎn)載于:https://www.cnblogs.com/Staceyacm/p/11333463.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的楼兰图腾(权值线段树)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 代还信用卡什么意思?代还信用卡步骤详解
- 下一篇: mysql 主主复制的配置流程