码迷,mamicode.com
首页 > 其他好文 > 详细

2018 07 14 题解

时间:2018-07-16 11:10:07      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:oiv   ida   vld   tps   sign   zid   不能   mdx   zcm   

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 个操作或询问:

  1. 操作:节点 p 权值增加 w。
  2. 询问:两点(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 题解

标签:oiv   ida   vld   tps   sign   zid   不能   mdx   zcm   

原文地址:https://www.cnblogs.com/LonelyRyan/p/9315913.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!