【NOIP2016提高A组模拟8.15】Throw
题目
分析
首先对于一个状态(a,b,c),假定a<=b<=c;
现在考虑一下这个状态,的转移方案:
\]
\]
我们将一个状态两边向中间转移后的状态设为这个状态的父亲,我们发现,这刚好形成了一颗树。
那么从起点和终点都分别向父亲跳,用hash判重,如果有交点就输出yes以及ans,反之。
但这显然会超时。
我们用二元组(l,r)来代表每一个状态,l=b-a,r=c-b。(显然根节点就是l=r的二元组)
当这个状态向父亲跳时,就变成
\]
发现这样转移就类似于辗转相除法!
用倍增求lca就可以了。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=10000007;
const long long N=50005;
using namespace std;
long long b[4],n=3,m,t[4],a[4],mi[35],deep,deep1,a1[4],b1[4],f[2][2],dd,l,r,ll,rr,ans;
bool q;
long long do1(long long x)
{
long long k=0,p;
while(x>0)
{
sort(a+1,a+3+1);
k=0;
if(l==r)
{
q=false;
break;
}
if(l>r)
{
if(l%r==0) k--;
k+=l/r;
p=r;
if(x-k>=0)
{
l-=k*r;
x-=k;
a[3]-=(k-k/2)*p*2;
a[2]-=(k/2)*p*2;
}
else
{
l-=x*r;
k=x;
a[3]-=(k-k/2)*p*2;
a[2]-=(k/2)*p*2;
break;
}
}
else
{
if(r%l==0) k--;
k+=r/l;
p=l;
if(x-k>=0)
{
r-=k*l;
x-=k;
a[1]+=(k-k/2)*p*2;
a[2]+=(k/2)*p*2;
}
else
{
r-=x*l;
k=x;
a[1]+=(k-k/2)*p*2;
a[2]+=(k/2)*p*2;
break;
}
}
}
}
long long do2(long long x)
{
long long k=0,p;
while(x>0)
{
sort(b+1,b+3+1);
k=0;
if(ll==rr)
{
q=false;
break;
}
if(ll>rr)
{
if(ll%rr==0) k--;
k+=ll/rr;
p=rr;
if(x-k>=0)
{
ll-=k*rr;
x-=k;
b[3]-=(k-k/2)*p*2;
b[2]-=(k/2)*p*2;
}
else
{
ll-=x*rr;
k=x;
b[3]-=(k-k/2)*p*2;
b[2]-=(k/2)*p*2;
break;
}
}
else
{
if(rr%ll==0) k--;
k+=rr/ll;
p=ll;
if(x-k>=0)
{
rr-=k*ll;
x-=k;
b[1]+=(k-k/2)*p*2;
b[2]+=(k/2)*p*2;
}
else
{
rr-=x*ll;
k=x;
b[1]+=(k-k/2)*p*2;
b[2]+=(k/2)*p*2;
break;
}
}
}
}
int main()
{
for(long long i=1;i<=n;i++) scanf("%lld",&a[i]);
for(long long i=1;i<=n;i++) scanf("%lld",&b[i]);
mi[0]=1;
for(long long i=1;i<=33;i++)
mi[i]=mi[i-1]*2;
sort(a+1,a+3+1);
sort(b+1,b+3+1);
f[0][0]=a1[0]=a[2]-a[1];
f[0][1]=a1[1]=a[3]-a[2];
f[1][0]=b1[0]=b[2]-b[1];
f[1][1]=b1[1]=b[3]-b[2];
deep=1;
deep1=1;
while(a1[0]!=a1[1])
{
long long k=0,p;
if(a1[0]>a1[1])
{
p=a1[1];
if(!(a1[0]%a1[1]))
{
k=a1[0]/a1[1]-1;
deep+=k;
a1[0]-=k*a1[1];
}
else
{
k=a1[0]/a1[1];
deep+=k;
a1[0]%=a1[1];
}
}
else
{
p=a1[0];
if(!(a1[1]%a1[0]))
{
k=a1[1]/a1[0]-1;
deep+=k;
a1[1]-=k*a1[0];
}
else
{
k=a1[1]/a1[0];
deep+=k;
a1[1]%=a1[0];
}
}
}
while(b1[0]!=b1[1])
{
long long k=0,p;
if(b1[0]>b1[1])
{
p=b1[1];
if(!(b1[0]%b1[1]))
{
k=b1[0]/b1[1]-1;
deep1+=k;
b1[0]-=k*b1[1];
}
else
{
k=b1[0]/b1[1];
deep1+=k;
b1[0]%=b1[1];
}
}
else
{
p=b1[0];
if(!(b1[1]%b1[0]))
{
k=b1[1]/b1[0]-1;
deep1+=k;
b1[1]-=k*b1[0];
}
else
{
k=b1[1]/b1[0];
deep1+=k;
b1[1]%=b1[0];
}
}
}
sort(a+1,a+3+1);
sort(b+1,b+3+1);
if(deep>deep1)
{
deep=deep^deep1;
deep1=deep^deep1;
deep=deep^deep1;
f[0][0]=f[0][0]^f[1][0];
f[1][0]=f[0][0]^f[1][0];
f[0][0]=f[0][0]^f[1][0];
f[0][1]=f[0][1]^f[1][1];
f[1][1]=f[0][1]^f[1][1];
f[0][1]=f[0][1]^f[1][1];
a[1]=a[1]^b[1];
b[1]=a[1]^b[1];
a[1]=a[1]^b[1];
a[2]=a[2]^b[2];
b[2]=a[2]^b[2];
a[2]=a[2]^b[2];
a[3]=a[3]^b[3];
b[3]=a[3]^b[3];
a[3]=a[3]^b[3];
}
ans=deep1-deep;
while(deep<deep1)
{
long long k=0;
if(f[1][0]>f[1][1])
{
if(f[1][0]%f[1][1]==0) k--;
k+=f[1][0]/f[1][1];
long long p=f[1][1];
if(deep1-k>=deep)
{
f[1][0]-=k*f[1][1];
deep1-=k;
b[3]-=(k-k/2)*p*2;
b[2]-=(k/2)*p*2;
}
else
{
f[1][0]-=(deep1-deep)*f[1][1];
k=deep1-deep;
b[3]-=(k-k/2)*p*2;
b[2]-=(k/2)*p*2;
break;
}
}
else
{
if(f[1][1]%f[1][0]==0) k--;
k+=f[1][1]/f[1][0];
long long p=f[1][0];
if(deep1-k>=deep)
{
f[1][1]-=k*f[1][0];
b[1]+=(k-k/2)*p*2;
b[2]+=(k/2)*p*2;
deep1-=k;
}
else
{
f[1][1]-=(deep1-deep)*f[1][0];
k=deep1-deep;
b[1]+=(k-k/2)*p*2;
b[2]+=(k/2)*p*2;
break;
}
}
}
deep1=deep;
dd=deep;
sort(a+1,a+3+1);
sort(b+1,b+3+1);
for(long long i=33;i>=0;i--)
{
if(mi[i]<=dd)
{
q=true;
l=f[0][0];
r=f[0][1];
for(long long j=1;j<=n;j++) a1[j]=a[j];
do1(mi[i]);
if(q)
{
ll=f[1][0];
rr=f[1][1];
for(long long j=1;j<=n;j++) b1[j]=b[j];
do2(mi[i]);
if(q)
{
sort(a+1,a+3+1);
sort(b+1,b+3+1);
if(a[1]==b[1] && a[2]==b[2] && a[3]==b[3])
{
for(long long j=1;j<=n;j++) a[j]=a1[j];
for(long long j=1;j<=n;j++) b[j]=b1[j];
continue;
}
f[0][0]=a[2]-a[1];
f[0][1]=a[3]-a[2];
f[1][0]=b[2]-b[1];
f[1][1]=b[3]-b[2];
ans+=mi[i]*2;
}
else
{
for(long long j=1;j<=n;j++) a[j]=a1[j];
for(long long j=1;j<=n;j++) b[j]=b1[j];
}
}
else
{
for(long long j=1;j<=n;j++) a[j]=a1[j];
}
}
}
if(a[1]==b[1] && a[2]==b[2] && a[3]==b[3])
{
printf("YES\n%lld",ans);
return 0;
}
l=f[0][0];
r=f[0][1];
do1(1);
ll=f[1][0];
rr=f[1][1];
do2(1);
sort(a+1,a+3+1);
sort(b+1,b+3+1);
ans+=2;
if(a[1]==b[1] && a[2]==b[2] && a[3]==b[3]) printf("YES\n%lld",ans);
else printf("NO");
}
【NOIP2016提高A组模拟8.15】Throw的更多相关文章
- NOIP2016提高A组模拟10.15总结
第一题,就是将原有的式子一步步简化,不过有点麻烦,搞了很久. 第二题,枚举上下边界,维护一个单调队列,二分. 比赛上没有想到,只打了个暴力,坑了80分. 第三题,贪心,最后的十多分钟才想到,没有打出来 ...
- 【NOIP2016提高A组模拟10.15】打膈膜
题目 分析 贪心, 先将怪物按生命值从小到大排序(显然按这个顺序打是最优的) 枚举可以发对少次群体攻击, 首先将所有的群体攻击发出去, 然后一个一个怪物打,当当前怪物生命值大于2,如果还有魔法值就放重 ...
- 【NOIP2016提高A组模拟10.15】最大化
题目 分析 枚举两个纵坐标i.j,接着表示枚举区域的上下边界, 设对于每个横坐标区域的前缀和和为\(s_l\),枚举k, 显然当\(s_k>s_l\)时,以(i,k)为左上角,(j,k)为右下角 ...
- 【NOIP2016提高A组模拟10.15】算循环
题目 分析 一步步删掉循环, 首先,原式是\[\sum_{i=1}^n\sum_{j=1}^m\sum_{k=i}^n\sum_{l=j}^m\sum_{p=i}^k\sum_{q=j}^l1\] 删 ...
- 【NOIP2016提高A组模拟9.15】Map
题目 分析 发现,当原图是一棵树的时候,那么新建一条边后,就会变成环套树, 而环内的所有点对都是安全点对,如果环中有k个点,答案就是\(k(k-1)\) 联想到,当把原图做一遍tarjan缩点,每个环 ...
- 【NOIP2016提高A组模拟9.15】Osu
题目 分析 考虑二分答案, 二分小数显然是不可取的,那么我们将所有可能的答案求出来,记录在一个数组上,排个序(C++调用函数很容易超时,手打快排,时间复杂度约为\(O(>8*10^7)\),但相 ...
- 【NOIP2016提高A组模拟9.15】Math
题目 分析 因为\((-1)^2=1\), 所以我们只用看\(\sum_{j=1}^md(i·j)\)的值模2的值就可以了. 易证,一个数x,只有当x是完全平方数时,d(x)才为奇数,否则为偶数. 那 ...
- 【NOIP2016提高A组模拟8.15】Garden
题目 分析 其实原题就是[cqoi2012][bzoj2669]局部极小值. 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点) ...
- 【NOIP2016提高A组模拟8.15】Password
题目 分析 首先我们知道,原A序列其实表示一个矩阵,而这个矩阵的对角线上的数字就是答案B序列. 接着\(a.b>=gcd(a,b)\),所以序列A中的最大的数就是ans[1],第二大的数就是an ...
随机推荐
- Ubuntu虚拟机共享文件夹的1234
第一 在虚拟机内添加路径 进入虚拟机软件,点开工具栏上方虚拟机,点击设置,选择选项,查看共享文件夹,点击添加,下一步 第二: 第三 点击启用此共享 点击完成 第四 查看共享的文件 在mnt里可以看到S ...
- 【HANA系列】SAP 【第一篇】EXCEL连接SAP HANA的方法(ODBC)
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP [第一篇]EXCEL连接 ...
- CodeSmith 找不到请求的 .Net Framework Data Provider
连接数据库时候报标题的错误解决方案 安装mysql-connector-net-6.8.7.msi,下载地址:http://dev.mysql.com/downloads/connector/net/ ...
- CentOS安装Netdata进行系统监控
偶然间在知乎看到了Netdata这个东西 看到它华丽的界面 顿时心动 gkd gkd #准备 yum install autoconf automake curl gcc git libmnl-dev ...
- Android 子线程无法刷新UI界面
问题:在Android开发中,子线程无法直接更改UI界面视图的刷新 这个时候 Handler 起到了至关重要的作用. 简单来说 , Handler就是用来传递消息的. Handler可以当成子线程与主 ...
- c#中抽象类和接口的相同点跟区别
下面是自己写的一个demo,体现抽象类和接口的用法. using System; using System.Collections.Generic; using System.Linq; using ...
- Python中.format()常见的用法
format()格式化输出 format():把传统的%替换为{}来实现格式化输出 format()常见的用法: ') >>>' 其实就是format()后面的内容,填入大括号中 ' ...
- 初步学习jquery学习笔记(五)
jquery学习笔记五 jquery遍历 什么是遍历? 从某个标签开始,按照某种规则移动,直到找到目标标签为止 标签树 <div> <ul> <li> <sp ...
- IDEA怎么关闭暂时不用的工程
一.隐藏 二.隐藏之后显示显示模块 原文地址:https://blog.csdn.net/woshilovetg/article/details/82774437
- RabbitMQ入门教程(十四):RabbitMQ单机集群搭建
原文:RabbitMQ入门教程(十四):RabbitMQ单机集群搭建 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ...