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 ...
随机推荐
- 【水滴石穿】rn_statusbar
先放项目地址https://github.com/hezhii/rn_statusbar 来看一下效果 咩有感觉很怎么样,看代码 根入口文件 //index.js //看代码我们知道入口是app.js ...
- onethink二级导航调用
<ul class="nav-main">//添加tree参数 <think:nav name="nav" tree="true&q ...
- Linux之Shell1
1.输出命令:echo echo [选项] [输出内容] : -e 支持反斜线控制的字符转换.(类似于C语言的\) \\ 输出\本身 \t Tab键 \n 换行符 \f 换页符 ...
- MAC+VS Code+C/C++调试配置
目录 VS Code C/C++ 环境配置 添加工作区文件夹 Say Hello world 关于三个配置文件--Debug 原地址 VS Code C/C++ 环境配置 添加工作区文件夹 虽然代码能 ...
- Directx11教程(62) tessellation学习(4)
原文:Directx11教程(62) tessellation学习(4) 现在看看四边形在不同tess factor时,四边形细分的细节,下图是tess factor1-8时候的细分.te ...
- objectarx之两条曲线最短距离
double CCommonFuntion::GetLineDistance(AcDbObjectId& Line1, AcDbObjectId& Line2){ AcGeLineSe ...
- 微信小程序组件——详解wx:if elif else的用法
背景 在学习微信小程序开发wxml页面时,需要使用if,else来判断组件是否进行展示,代码如下 <view wx:if="{{is_login==1}}">成功登录& ...
- 设备 VMnet0 上的网络桥接当前未在运行。
早上,我打开我的虚拟机,却发现一个问题, 桥接网络怎么都连接不上. 报的是如下的错误 ------------------------------ 设备 VMnet0 上的网络桥接当前未在运行.该虚拟 ...
- hdu 1272 使用set和并查集
http://acm.hdu.edu.cn/showproblem.php?pid=1272 这道题就是求图是不是连通无环,我觉得其实就是看看图是不是一棵最小生成树. 所以要是图满足条件,就必然有n个 ...
- gpu命令cuda命令
# device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")os.envi ...