2018 07 14 題解
阿新 • • 發佈:2018-07-16
ret dot eat vid obi logs 既然 scroll 中位數
2018 07 14
T1
Description
給出一個長度為 n 的序列 A,求這個序列的最長上升子序列的長度。
Hint
O(NlogN)模板題,不贅述了
Code
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define siz 100010
using namespace std;
int n, m, len;
int a[siz], dp[siz];
int sear(int dat) {
int l = 0, r = len, mid, re;
while(l <= r) {
mid = (l + r) / 2;
if(dp[mid] >= dat) r = mid - 1;
else re = mid, l=mid + 1;
}
return re;
}
int main() {
scanf ("%d",&n);
for(int i=1; i<=n; ++i) scanf("%d",&a[i]);
dp[0] = -2147483647;
for(int i=1; i<=n; ++i) {
if(a[i] > dp[len]) dp[++len] = a[i];
else {
int j = sear(a[i]);
dp[j + 1] = a[i];
}
}
printf("%d",len);
return 0;
}
T2
Description
給出一棵大小為 n 的樹,根為 1。點有點權。給出 m 個操作或詢問:
- 操作:節點 p 權值增加 w。
- 詢問:兩點(u,v)的路徑點權和。
Hint
Code
T3
Description
給出一個長度為 n 的排列 A,求這個排列有多少個長度為奇數的子串中位數是 mid。
Hint
首先知曉概念:子串是連續的
既然是長度為奇數的子串,中位數為mid,那一定是以mid為中位數的
又因為子串是連續的,所以我們只要以mid為界向兩邊延伸,如果大於mid的數和小於mid的數數量相等,這一串就符合題意.
這裏就有一個普通的優化,記大於mid的數為+1,小於mid的為-1,mid為0
向左累加,統計累計和為i的個數為L[i],同理向右,統計r[i]
答案即為$\sum {L[i]*R[-i]}$
註意 C++不能開負數組
Code
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mid 1000000
#define siz 2000100
using namespace std;
int n, m, pos, cntl, cntr;
int a[siz], l[siz], r[siz];
long long ans;
int main() {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i) {
scanf("%d",&a[i]);
if(a[i] < m) a[i] = -1;
else if(a[i] == m) { pos = i; a[i] = 0;}
else a[i] = 1;
}
for(int i=pos; i; i--) {
cntl += a[i];
l[cntl + mid] ++;
}
for(int i=pos; i<=n; ++i) {
cntr += a[i];
r[cntr + mid] ++;
}
for(int i=-(n-1); i<n; ++i) ans += (l[mid + i] * r[mid - i]);
printf("%ld",ans);
return 0;
}
?
2018 07 14 題解