HGOI 20190816 省常中互测8
Problem A
有两条以(0,0)为端点,分别经过(a,b),(c,d)的射线,你要求出夹在两条射线
中间,且距离(0,0)最近的点(x,y)对于$100\%$的数据满足$1 \leq T \leq 10^6 , 0 \leq a,b,c,d \leq 10^9$
Solution :
每次删除一个下面那条线斜率下取整这块三角形,然后将y坐标下移,
每一次分治下去,最后一定会存在一个时刻$(1,1)$合法,此时回溯回去即可。
由于分治前后,线段的相对位置不变,不会存在新的点更优,所以最后生成的答案一定是最优的。
每次查询的复杂度大约是$O(n)$的。
具体可以看下面$a = 2,b = 7,c = 4,d = 10$的求值方法。
# include <bits/stdc++.h>
# define int long long
using namespace std;
void work(int a,int b,int c,int d,int &x,int &y)
{
if (a<b&&c>d) { x=,y=; return; }
if (a*d>b*c) work(c,d,a,b,x,y);
else if (a>=b) work(b,a,d,c,y,x);
else {
int t=d/c;
work(a,b-t*a,c,d-t*c,x,y);
y+=t*x;
}
}
main()
{
int T; scanf("%lld",&T);
while (T--) {
int a,b,c,d; scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
int x,y; if (a*d>b*c) swap(a,c),swap(b,d);
work(a,b,c,d,x,y); printf("%lld %lld\n",x,y);
}
return ;
}
A.cpp
Problem B graph
给出$n$个点$m$条边的连通二分图$G$ ,给出$Q$组询问,每次求出$u,v$路径上(不一定是简单路径)的权值最大值。
一条路径的权值定义为,这条边经过所有节点的异或和,同一个点经过多次将会被计算多次。
对于$100\%$的数据满足$1 \leq n,m,Q\leq t\times 10^5$
Solution : 二分图性质题。
对于一个图$G$是二分图,满足一定是两个集合的点来考虑。
我们考虑$u - v$的一条路径,如果走简单路径就是$u \ xor \ v$的权值,如果走一个来回,那么就是$0$的权值。
所以,对于任意两点的任意一条路径,我们都可以考虑两个相邻点权值是否被异或到路径的答案中,可以同时取反。
对于询问中处在相同集合的两个点,路径经过点的数目一定是奇数,选择若干个点对翻转一定会造成奇数个节点的权值被选择(一个极端的例子就是什么节点都不翻转状态)
由于二分图的连通性,问题就等价于求在所给点集里找出奇数个点,使他们的异或和最大。
在询问中处在相异集合里的两个点,路径经过点的数目一定是偶数,选择若干个点对翻转一定会造成偶数个节点的权值被选择(一个极端的例子就是什么节点都不翻转状态)
由于二分图的连通性,问题就等价于求在所给点集里找出偶数个点,使他们的异或和最大。
在所给点集里找出偶数个点,使他们的异或和最大。这个问题可以将相邻两个点的点权插入到线性基里面,然后求出线性基中的最大值即可。
在所给点集里找出奇数个点,使他们的异或和最大。这个问题可以将相邻两个点的点权插入到线性基里面,强制地任意的取一个节点必须被异或,然后求出线性基中的最大值即可。
由于可以预处理这两个答案,最后询问的复杂度就是$O(1)$的,最终,本题的复杂度就是$O(n+Q)$的。
# include <bits/stdc++.h>
using namespace std;
const int N=5e5+;
struct rec{
int pre,to;
}a[N<<];
int head[N],n,m,q,val[N],tot,col[N];
void adde(int u,int v)
{
a[++tot].pre=head[u];
a[tot].to=v;
head[u]=tot;
}
struct Linear_Basis{
int d[];
Linear_Basis() {
memset(d,,sizeof(d));
}
void insert(int x) {
for (int i=;i>=;i--)
if (x&(<<i)) {
if (!d[i]) { d[i]=x; break;}
else x^=d[i];
}
}
int query(int ret) {
for (int i=;i>=;i--)
if ((ret^d[i])>ret) ret^=d[i];
return ret;
}
}B;
void dfs(int u,int c)
{
col[u]=c;
for (int i=head[u];i;i=a[i].pre) {
int v=a[i].to; if (col[v]) continue;
dfs(v,-c);
}
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
for (int i=;i<=n;i++) scanf("%d",&val[i]);
for (int i=;i<=m;i++) {
int u,v; scanf("%d%d",&u,&v);
adde(u,v); adde(v,u);
}
dfs(,);
for (int i=;i<n;i++) B.insert(val[i]^val[i+]);
int same = B.query(val[]);
int diff = B.query();
while (q--) {
int u,v;
scanf("%d%d",&u,&v);
if (col[u]==col[v]) printf("%d\n",same);
else printf("%d\n",diff);
}
return ;
}
B.cpp
Problem C geo
平面直角坐标系中有$n$个点$(x_i,y_i)$,求出有多少个二次函数$y = x^2 + bx +c$经过至少两个点,并且任何点都不在这个函数的上方。
对于$100\%$的数据,满足$n\leq 2\times 10^5$
Solution :
对于点$(x,y)$在$y = x^2 + bx + c$下方的条件是$x^2 + bx + c \geq y$
化简后就是$bx + c\geq y - x^2 $
对于所有的点$(x,y)$都是一定的,如果我们把每个点的坐标转化为$(x,y-x^2)$,
问题就转化为求一个一次函数$y = bx + c$使得这个一次函数至少经过两个点并且在所有点上方。
问题就等价于求出一个点集凸包的上部的边的条数。
即所有在左极点和右极点连线严格上方的点数+1。
复杂度就是$O(n)$的。
#include<bits/stdc++.h>
#define ll long long
#define inf (1e18)
using namespace std;
struct p{double x,y;}a[],s[],l,r;
ll n,k=,top=,ans;
double cross(p a,p b,p c){return(b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}
double dis(p a,p b){return sqrt((b.y-a.y)*(b.y-a.y)+(b.x-a.x)*(b.x-a.x));}
bool cmp(p x,p y)
{
double tmp=cross(a[],x,y);
return tmp>||(tmp==&&dis(a[],x)<dis(a[],y));
}
int main()
{
scanf("%lld",&n);
for(ll i=;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y),a[i].y-=a[i].x*a[i].x;
for(ll i=;i<=n;i++)if((a[k].y>a[i].y)||(a[k].y==a[i].y&&a[i].x<a[k].x))k=i;
swap(a[k],a[]),sort(a+,a++n,cmp),s[]=a[];
for(ll i=;i<=n;i++)
{
while(top>&&cross(s[top-],a[i],s[top])>=)top--;
s[++top]=a[i];
}
l={inf*1.0,inf*1.0},r={inf*-1.0,inf*-1.0};
for(ll i=;i<=top;i++)
{
if(s[i].x<l.x)l=s[i];else if(s[i].x==l.x&&s[i].y>l.y)l=s[i];
if(s[i].x>r.x)r=s[i];else if(s[i].x==r.x&&s[i].y>r.y)r=s[i];
}
for(ll i=;i<=top;i++)if(cross(l,r,s[i])>)ans++;
printf("%lld\n",ans+);
return ;
}
C.cpp
HGOI 20190816 省常中互测8的更多相关文章
- HGOI20190814 省常中互测7
Problem A 中间值 对于$2$个非严格单增序列$\{A_n\} , \{B_n\}$,维护下列两个操作: 1 x y z: (x=0)时将$A_y = z$ , (x=1)时将$B_y = z ...
- HGOI20190813 省常中互测6
Problem A 蛋糕 将$n \times m $大小的蛋糕切成每块为$1 \times 1$大小的$n\times m$块. 交换任意两块蛋糕的切割顺序的方案算作一种. 对于$100 \%$的数 ...
- HGOI20190811 省常中互测4
Problem A magic 给出一个字符串$S$,和数字$n$,要求构造长度为$n$只含有小写字母的字符串$T$, 使得在$T$中存在删除且仅删除一个子串使得$S=T$成立. 输出$T$的构造方案 ...
- HGOI20190810 省常中互测3
Problem A 夏洛特 若当前处在点$(x,y)$下一时刻可以向该点四周任意方向走动一步, 初始在$(0,0)$是否存在一条合法的路线满足下列$n$个限制: 每一个限制形如$t_i , x_i ...
- HGOI20190809 省常中互测2
Problem A 时之终结 构造一个含有$n$个节点的无重边无自环的有向图, 使得从$1$出发,每一次经过一条$(u,v) (u < v)$的边到达节点$n$的方案恰好有$y$种. 对于$10 ...
- HGOI20190808 省常中互测1
Problem A sum 给出$n$个元素的序列$\{a_i\}$,求出两个不相交连续子序列的最大元素和. 即对于$1 \leq A \leq B \leq C \leq D \leq n$最大化 ...
- HGOI20190812 省常中互测5
Task 1 辩论 有N 个参加辩论的候选人,每个人对这两个议题都有明确的态度,支持或反对.作为组织者,小D 认真研究了每个候选人,并给每个人评估了一个非负的活跃度,他想让活跃度之和尽可能大.选出的候 ...
- HGOI 20190821 慈溪一中互测
Problem A 给出一个$n$个点$m$条边的仙人掌图(每条边最多处于一个简单环中). 使用$c$种颜色对这张图中的顶点染色,使得每一条无向边连接的两个点颜色不同. 求染色的方案数,$mod \ ...
- 【2018集训队互测】【XSY3372】取石子
题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...
随机推荐
- Oracle-DDL 3- 触发器
DDL-数据定义语句: 四.触发器 -- 触发器(trigger),与某些特定的操作绑定,当达到触发条件后会自动触发--主要用来将某些操作的过程记录下来,或者阻止某些非法的操作,保护数据 /*触发条件 ...
- Centos 安装Pycharm 并移动到桌面。
版权声明:版权所有.未经同意不得转发,装载 https://blog.csdn.net/limingyue0312/article/details/81805826 1.下载pycharm软件包 网页 ...
- Intellij IDEA中使用Debug调试
转自:https://blog.csdn.net/zj420964597/article/details/78662299只是为了方便学习技术,少走弯路,如果有异议,请留言,及时处理!!!
- 【笔记】vue实现简单项目和页面跳转
此项目适合不会前端,不会vue的人. 不会vue真正的开发,这里用vue和vant-ui简单搭一个商城app的tabbar和页面跳转. 装vue-cli3.0 根据官网快速上手搭建vant项目,官网 ...
- ajax实现异步操作实例1
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- js三级内联
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- C# 文件基本操作
概括的说,File,FileInfo,FileStream是用于文件 I/O 的类,StreamReader是用于从流读取和写入流的类,使用之前都需using System.IO. 先定义一个TXT文 ...
- oracle 使用问题
12541: 典型的listener.ora 文件内容: SID_LIST_LISTENER = (注册到监听器的service name所在区域) (SID_LIST = (SID_DE ...
- php 多肽实例
多态定义:只关心一个接口或者基类,而不关心一个对象的具体类.(同一类型,不同结果) 这里两个例子: 第一个,我们发现,基类定义了标准,子类进行了自我规则的实现.这是多态的一个要求.同时,这是满足重写: ...
- 解决xshell小键盘输入时串码(干货!!)
点击文件——属性 点击终端,修改为Linux即可