Light OJ 1402 (Dp + 树状数组)
来源:互联网 发布:淘宝大码女装秋装 编辑:程序博客网 时间:2024/06/07 05:26
题目:
[LINK](http://www.lightoj.com/volume_showproblem.php?problem=1402)给你一些点(SRT, R);按照SRT排序, 然后再坐标系中画出这些点, 连成一条线。线会有峰点(peak),一个点是峰点, 相邻两个点的 R 值都比它小 或 大。然后WARush 要丧病的忽略一些点,(忽略第X点后,第 X 后面的点会前移! ) 会形成新的线。 然后题目要求输出所有线条中刚好有 K 个峰点的**不同线条**的数量。
分析:
题目中 单个点 和 没有点 都算一种情况。先把所有点排序, 然后依次画图, 统计线条数。对于 第 i 个点画图时 : 枚举 K 值 当K == 0时, 我们可以得出: 上升线条 Up = [比 Ri 低的点的数目] + [总结点数] + [上升线条尾端点值比 Ri 低的数] 下降线条 Down 同理。 故Dp[k] = Up + Down + 节点node 数。 当 K > 0 时。 : 上升线条 Up(k) = [上升线条 Up(k) 中尾端点比 Ri 小的线条数] + \ [ 下降线条 Down(k-1) 中尾端点比 Ri 小的线条数]. 下降线条 Down(k) 同理。怎么求这些值? 用树状数组维护就好了。
Code:
#include <bits/stdc++.h>using namespace std;typedef unsigned int U32;const int maxn = 10000 + 131;inline int lowbit(int x) { return x & (-x);}///树状数组struct BIT { U32 Num[maxn]; int N; void INIT(int n) { N = n; memset(Num, 0, sizeof(Num)); } void Add(int x, U32 val) { while(x <= N) { Num[x] += val; x += lowbit(x); } } U32 Sum(int x) { U32 ret = 0; while(x > 0) { ret += Num[x]; x -= lowbit(x); } return ret; } U32 Sec(int L, int R) { return Sum(R) - Sum(L-1); }};/// DP 状态struct State { BIT Up, Down, Node; void INIT(int n) { Up.INIT(n); Down.INIT(n); Node.INIT(n); }};struct Data { int s, r; bool operator < (const Data& a) const { return this->s < a.s; }};Data node[maxn];State Dp[60];int R_n[maxn];int main() { int T; scanf("%d",&T); for(int kase = 1; kase <= T; ++kase) { int n, K; scanf("%d%d",&n, &K); for(int i = 0; i < n; ++i) { scanf("%d%d",&node[i].s, &node[i].r); R_n[i] = node[i].r; } sort(R_n, R_n+n); int C = unique(R_n, R_n+n) - R_n; int Max = -1; for(int i = 0; i < n; ++i) { node[i].r = lower_bound(R_n, R_n+C, node[i].r)-R_n+1; Max = max(Max, node[i].r); } sort(node, node+n); ///离散化结束 for(int i = 0; i <= K; ++i) Dp[i].INIT(Max); for(int i = 0; i < n; ++i) { int h = node[i].r; for(int k = 0; k <= K; ++k) { //相同点会造成相同的线条, 所以要减去。 U32 Sum_Up = -Dp[k].Up.Sec(h,h); U32 Sum_down = -Dp[k].Down.Sec(h,h); U32 Sum_node = -Dp[k].Node.Sec(h,h); Sum_Up += Dp[k].Up.Sum(h-1) + Dp[k].Node.Sum(h-1); Sum_down += Dp[k].Down.Sec(h+1, Max) + Dp[k].Node.Sec(h+1,Max); if(k == 0) Sum_node++; else { Sum_Up += Dp[k-1].Down.Sum(h-1); Sum_down += Dp[k-1].Up.Sec(h+1, Max); } if(Sum_Up) Dp[k].Up.Add(h, Sum_Up); if(Sum_down) Dp[k].Down.Add(h, Sum_down); if(Sum_node) Dp[k].Node.Add(h, Sum_node); } } U32 Ans = 0; Ans = Dp[K].Down.Sum(Max) + Dp[K].Up.Sum(Max) + Dp[K].Node.Sum(Max); if(K == 0) Ans ++; printf("Case %d: %u\n",kase, Ans); } return 0;}
1 0
- Light OJ 1402 (Dp + 树状数组)
- Light OJ 1266(二维树状数组)
- Light OJ--1080-----Binary Simulation树状数组
- Light oj 1080 - Binary Simulation 【树状数组】
- Light oj 1112 - Curious Robin Hood(树状数组)
- Light oj 1112-Curious Robin hood --树状数组
- light oj 1080 线段树和树状数组
- 树状数组初步 Light OJ 1112 Curious Robin Hood
- Light OJ 1188 Fast Queries (树状数组离线)
- scu oj 4441 Necklace(dp+树状数组)
- Light OJ 1415 Save the Trees (dp+块状数组)
- Light OJ:1094 Farthest Nodes in a Tree(树状DP+统计树的最大直径)
- light oj 1032 数位DP
- light OJ 1205 数位DP
- light OJ 1068 数位DP
- light oj 1140 数位dp
- light oj 1422,区间dp
- Light OJ 1231(背包dp)
- RabbitMQ基础概念详细介绍
- Java字符串处理String、StringBuilder、StringBuffer类效率分析
- Git 基本用法大全
- location.href/location.search/location.pathname区别及用法
- MyBatis 通过包含的jdbcType类型
- Light OJ 1402 (Dp + 树状数组)
- Android中如何获取应用版本号
- 实习入职第二天:Handler.removeMessages的作用
- 一个无锁消息队列引发的血案(三)——地:q3.h 与 RingBuffer
- 高质量的UI组件下载地址暂存
- 移植QT5.4.0到ARM开发板
- BZOJ 4552: [Tjoi2016&Heoi2016]排序
- TinyPNG---一个压缩PNG的神站
- Spring 开启Annotation <context:annotation-config>和 <context:component-scan>诠释及区别