Bishops Alliance—— 最大上升子序列
原题链接:http://codeforces.com/gym/101147/problem/F
题意:n*n的棋盘,给m个主教的坐标及其私有距离p,以及常数C,求位于同一对角线上满足条件:dist(i, j) >= p[i]^2 + p[j]^2 + C
的主教集合的元素个数最大值。
解题思路:
上述条件可以等价为:
d(j) - d(i) +1 >= p[i]^2 + p[j]^2 + C // d(i) 为第i个主教相对于该对角线顶点的距离
d(j) - p[j]^2 - C + 1>= d(i) + p[i]^2
设 f(i) = d(i) + p[i] ^2, g(i) = d(i) - p[i]^2 - C + 1
下面考虑一条对角线,设 c[x] 为长度为x 的最后一个主教编号,例如c[len] = i 代表长度为len的防线最后一个主教编号为i。
(特别的,c[0] = 0, f(0) = -INF )
首先将该对角线上的主教按 d(i) 排序, len 为当前最大长度+1,依次查询每一个主教并同时更新最大长度, 伪代码如下:
对当前查询的主教u
j = lower_bound(c, c+len,u,cmp) - c
if j =len && g(u) >= f(c[j-1])
c[len++] = u
if j != len && g(u) >= f(c[j-1])
c[j] = u
注意: 数据范围为 LL
代码如下:
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = +;
typedef long long LL;
#define INF 999999999999999999LL
vector<int> D1[*maxn];
vector<int> D2[*maxn]; int c[maxn];
int row[maxn], col[maxn], p[maxn];
int n, m, C;
//计算对角线编号
int dig_id1(int x, int y) {return x-y+n;}
int dig_id2(int x, int y) {return x+y;} int d1(int i) {return min(row[i], col[i]);}
int d2(int i) {return min(n-row[i]+, col[i]);} LL f1(int i) {return !i ? -INF : d1(i) + LL(p[i])*p[i];}
LL f2(int i) {return !i ? -INF : d2(i) + LL(p[i])*p[i];} LL g1(int i) {return d1(i) - LL(p[i])*p[i] - C + ;}
LL g2(int i) {return d2(i) - LL(p[i])*p[i] - C + ;} bool cmpd1(int i, int j) {return d1(i) < d1(j);}
bool cmpd2(int i, int j) {return d2(i) < d2(j);}
bool cmp1(const int& a,const int& b) {return f1(a) < f1(b);}
bool cmp2(const int& a,const int& b) {return f2(a) < f2(b);}
LL (*f[])(int) ={
f1,
f2
};
LL (*g[])(int) = {
g1,
g2
};
bool (*cmp[])(const int& ,const int& ) = {
cmp1,
cmp2
}; int cal(vector<int> &D,int flag) {
if(!D.size()) return ;
if(flag == ) sort(D.begin(), D.end(), cmpd1);
else sort(D.begin(), D.end(), cmpd2);
for(int i = ; i <= D.size(); i++) c[i] = ;
int len = ;
int j;
for(int i = ; i < D.size(); i++){
int u = D[i];
j = lower_bound(c, c+len, u, cmp[flag]) - c;
if(j == len && g[flag](u) >= f[flag](c[j-])) {
c[len++] = u;
}
if(j != len && g[flag](u) >= f[flag](c[j-])) {
c[j] = u;
}
}
return len - ;
}
#define fin stdin
int main() {
// FILE * fin;
// fin = fopen("bishops.in", "r");
int T;
fscanf(fin, "%d", &T);
while(T--) {
fscanf(fin, "%d%d%d", &n, &m, &C);
for(int i = ; i <= *n; i++) D1[i].clear();
for(int i = ; i <= *n; i++) D2[i].clear();
for(int i = ; i <= m; i++) {
fscanf(fin, "%d%d%d", &row[i], &col[i], &p[i]);
int id1 = dig_id1(row[i], col[i]);
int id2 = dig_id2(row[i], col[i]);
D1[id1].push_back(i);
D2[id2].push_back(i);
}
int ans = ;
for(int i = ; i <= *n; i++) {
ans = max(ans, cal(D1[i], ));
ans = max(ans, cal(D2[i], ));
}
printf("%d\n", ans);
}
return ;
}
Bishops Alliance—— 最大上升子序列的更多相关文章
- GYM - 101147 F.Bishops Alliance
题意: 一个n*n的棋盘,有m个主教.每个主教都有自己的权值p.给出一个值C,在棋盘中找到一个最大点集.这个点集中的点在同一条对角线上且对于点集中任意两点(i,j),i和j之间的主教数(包括i,j)不 ...
- 【Mutual Training for Wannafly Union #1 】
A.Phillip and Trains CodeForces 586D 题意:过隧道,每次人可以先向前一格,然后向上或向下或不动,然后车都向左2格.问能否到达隧道终点. 题解:dp,一开始s所在列如 ...
- 2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest (ECPC 16) 题解
题目链接:http://codeforces.com/gym/101147 2017/8/27日训练赛,题目情况9/11,Rank 4/79. A. The game of Osho 题意:定义一个子 ...
- 2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest (ECPC 16)
A.The game of Osho(sg函数+二项展开) 题意: 一共有G个子游戏,一个子游戏有Bi, Ni两个数字.两名玩家开始玩游戏,每名玩家从N中减去B的任意幂次的数,直到不能操作判定为输.问 ...
- 用python实现最长公共子序列算法(找到所有最长公共子串)
软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
- [LeetCode] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列
A sequence of numbers is called arithmetic if it consists of at least three elements and if the diff ...
- [LeetCode] Is Subsequence 是子序列
Given a string s and a string t, check if s is subsequence of t. You may assume that there is only l ...
- [LeetCode] Wiggle Subsequence 摆动子序列
A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...
随机推荐
- Python数据分析与展示[第三周](pandas数据类型操作)
数据类型操作 如何改变Series/ DataFrame 对象 增加或重排:重新索引 删除:drop 重新索引 .reindex() reindex() 能够改变或重排Series和DataFrame ...
- 2019-1-17-一段能让-VisualStudio-炸掉的代码
title author date CreateTime categories 一段能让 VisualStudio 炸掉的代码 lindexi 2019-01-17 09:55:29 +0800 20 ...
- NOIP模拟 7.04
魔术球问题弱化版(ball.c/.cpp/.pas) [题目描述] 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球. (1)每次只能在某根柱子的最上面放球. ( ...
- 新一代互联网传输协议QUIC浅析
QUIC(Quick UDP Internet Connection)是谷歌制定的一种互联网传输层协议,它基于UDP传输层协议,同时兼具TCP.TLS.HTTP/2等协议的可靠性与安全性,可以有效减少 ...
- es6中的(=>)箭头函数
x => x * x 上面的箭头函数相当于: function (x) { return x * x; } 箭头函数相当于匿名函数,并且简化了函数定义. 箭头函数有两种格式,一种像上面的,只包含 ...
- @Transactional注解事务
打了这个注解的类或者方法表示该类里面的所有方法或者这个方法的事务由spring处理,来保证事务的原子性,即方法里面对数据库操作,如果失败则spring负责回滚操作,成功提交操作 一.特性 1.serv ...
- python 朴素算法
- css 的float和inline-block区别
CSS布局创建网站,浮动绝对占据了很大的比例.大块区域如主内容及侧边栏,以及在其中的小块区域,都可以看到浮动的影子.这里浮动是唯一的解决方案吗? 浮动通常表现正常,但有时候搞起来会很纠结.特别是处理内 ...
- Linux使用及命令
#命令模式下输入:光标移动到第34行第15个字符 <Enter>15l(这是小写的L) ctrl+u删除光标前面的字符 ctrl+j删除光标后面的字符 在Linux下用VIM打开大小几个G ...
- Java练习 SDUT-2787_加密术
加密术 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 加密技术是一种常用的安全保密手段,利用加密技术可以把重要的数据变 ...