洛谷P1637 三元上公升子串行

2022-05-01 10:36:09 字數 2244 閱讀 4967

p1637三元上公升子串行

提交  討論  題解  

最新討論更多討論

題目描述

erwin最近對一種叫"thair"的東西巨感興趣。。。

在含有n個整數的序列a1,a2......an中,

三個數被稱作"thair"當且僅當i求乙個序列中"thair"的個數。

輸入輸出格式

輸入格式:

開始乙個正整數n,

以後n個數a1~an。

輸出格式:

"thair"的個數

輸入輸出樣例

輸入樣例#1

input

42 1 3 4

output

2input

51 2 2 3 4

output

7對樣例2的說明:

7個"thair"分別是

1 2 3

1 2 4

1 2 3

1 2 4

1 3 4

2 3 4

2 3 4

輸出樣例#1

說明

約定 30%的資料n<=100

60%的資料n<=2000

100%的資料n<=30000

大資料隨機生成

0<=a[i]<=maxlongint

分析:這道題可以借鑑之前求逆序對那樣求,我們只需要求對於每乙個數i,在i之前比i小的數的個數和在i之後比i大的數的個數,相乘起來,最後將所有結果加起來就是答案,關鍵就是如何求出這些數的個數。可以利用樹狀陣列。先將資料離散化,先找小於i的,因為要嚴格小於,所以我們要先-1再查詢,然後新增進去,然後找大於i的,從後往前列舉,相當於我們找到i之後不大於i的個數,然後用n-i(i之後的數的個數)減去結果就是嚴格大於i的數的個數,最後統計一下答案即可。

如果將這道題推廣到要找k個數的情況,我們需要用到dp,則dp[i][j] = dp[k][j-1] + dp[k][j],其中k為小於i中最靠後的乙個數.

#include #include 

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

long

long d1[30010], d2[30010],ans1[30010],ans2[30010],dis[30010

],ans;

struct

node

a[30010

];int

n;void update(long

long x, intv)}

int sum(long

long

x)

return

cnt;

}void update2(long

long x, intv)}

int sum2(long

long

x)

return

cnt;

}bool

cmp(node a, node b)

intmain()

sort(a + 1, a + 1 +n, cmp);

dis[a[

1].id] = 1

;

int tot = 1

;

for (int i = 2; i <= n; i++)

for (int i = 1; i <= n; i++)

for (int i = n; i >= 1; i--)

for (int i = 1; i <= n; i++)

ans += ans1[i] *ans2[i];

printf(

"%lld\n

", ans);

return0;

}

三元上公升子串行 洛谷p1637

erwin最近對一種叫 thair 的東西巨感興趣。在含有n個整數的序列a1,a2.an中,三個數被稱作 thair 當且僅當i求乙個序列中 thair 的個數。輸入格式 開始乙個正整數n,以後n個數a1 an。輸出格式 thair 的個數 輸入樣例 1 4 50 18 3 4 6 8 1415 1...

P1637 三元上公升子串行

標籤 線段樹 離散化好題。題意 給定乙個長度為 首先,我們知道求滿足 那麼對於原問題,include include include define ri register int using namespace std const int maxn 30020 int n,a maxn int l ...

P1637 三元上公升子串行

對於這個題,我們對於每乙個數i,分別求出所有比它小的,在它前面的和 比它大的,在它後面的,然後把這兩個乘起來,然後再把這些積加起來就可以了 然而這樣直接做複雜度太高了,我們要優化,仿照樹狀陣列求逆序對的方法,我們就可以在可以接受的時間內求出並且解決問題了 include include includ...