TYVJ NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第二轮Day2题解

  肝了两题...

  T1一眼题,分解质因数,找出2的个数和5的个数取min输出

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=1000010,inf=1e9;
int n,m,T;
int fac2[maxn],fac5[maxn];
void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar();
    while(c<=‘9‘&&c>=‘0‘)k=k*10+c-‘0‘,c=getchar();
    k*=f;
}
int main()
{
    freopen("zero.in","r",stdin);
    freopen("zero.out","w",stdout);
    read(T);
    for(int i=1;i<=1000000;i++)
    {
        int x=i;fac2[i]=fac2[i-1];fac5[i]=fac5[i-1];
        for(;(x&1)==0;x>>=1)fac2[i]++;
        for(;x%5==0;x/=5)fac5[i]++;
    }
    while(T--)
    {
        read(m);read(n);
        int cnt2=fac2[m]-fac2[n]-fac2[m-n];
        int cnt5=fac5[m]-fac5[n]-fac5[m-n];
        printf("%d\n",min(cnt2,cnt5));
    }
    return 0;
}

  T2是个环套树题

  分三类:①两个点都在同个树上,求直径,两次bfs或者树形DP即可

      ②一个点在环上一个点在树上,答案为最大深度dep+len/2

      ③两个点在不同的树上,即求max(depi+depj+dis(i,j)),而dis(i,j)显然是<=len/2且递增的,用单调队列维护max(depj+dis(i,j)),队头与i距离超过len/2就出队,走一圈之后就可以算出这种情况的答案

  三类取max

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=500010,inf=1e9;
struct poi{int too,pre;}e[maxn];
int n,m,x,y,z,tot,ans,st,ed,cnt,len;
int mx1[maxn],mx2[maxn],d[maxn],last[maxn],isrt[maxn],rt[maxn],q[maxn];
void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar();
    while(c<=‘9‘&&c>=‘0‘)k=k*10+c-‘0‘,c=getchar();
    k*=f;
}
inline void add(int x,int y){e[++tot].too=y;e[tot].pre=last[x];last[x]=tot;}
void dfs(int x,int fa)
{
    d[x]=d[fa]+1;mx1[x]=d[x];mx2[x]=0;
    for(int i=last[x];i;i=e[i].pre)
    if(e[i].too!=fa&&!isrt[e[i].too])
    {
        dfs(e[i].too,x);
        if(mx1[e[i].too]>mx1[x])mx2[x]=mx1[x],mx1[x]=mx1[e[i].too];
        else if(mx1[e[i].too]>mx2[x])mx2[x]=mx1[e[i].too];
    }
    ans=max(ans,mx1[x]+mx2[x]-(d[x]<<1));
}
inline int dfs2(int x,int fa)
{
    if(x==ed)return len++,1;
    for(int i=last[x];i;i=e[i].pre)
    if(e[i].too!=fa)if(dfs2(e[i].too,x))
    return rt[++cnt]=x,isrt[x]=1,len++,1;
    return 0;
}
inline int dis(int x,int y){if(x>=y)return x-y;return len-(y-x);}
inline void work()
{
    int l=1,r=0;
    for(int i=(len>>1);i;q[++r]=i,i--)
    while(l<=r&&mx1[rt[q[r]]]+dis(q[r],cnt)<=mx1[rt[i]]+dis(i,cnt))r--;
    for(int i=cnt;i;i--)
    {
        while(l<=r&&(dis(q[l],i)>(len>>1)||q[l]==i))l++;
        ans=max(ans,mx1[rt[i]]+mx1[rt[q[l]]]+dis(q[l],i));
        while(l<=r&&mx1[rt[q[r]]]+dis(q[r],i)<=mx1[rt[i]])r--;
        q[++r]=i;
    }
}
int main()
{
    freopen("road.in","r",stdin);
    freopen("road.out","w",stdout);
    read(n);read(m);
    for(int i=1;i<n;i++)read(x),read(y),add(x,y),add(y,x);
    for(int i=1;i<=m;i++)
    {
        read(st);read(ed);ans=len=cnt=0;
        memset(isrt,0,sizeof(isrt));d[0]=-1;
        rt[++cnt]=ed;isrt[ed]=1;dfs2(st,0);
        for(int j=1;j<=cnt;j++)dfs(rt[j],0),ans=max(ans,mx1[rt[j]]+(len>>1));
        work();printf("%d\n",ans);
    }
    return 0;
}

时间: 2024-10-08 08:54:55

TYVJ NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第二轮Day2题解的相关文章

tyvj NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第一轮Day2题解

上星期打的...题有点水,好多人都AK了 T1排个序贪心就好了 #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> #define ll long long using namespace std; const int maxn=500010,inf=1e9; struct poi{int e,s;}a[maxn];

NOIP2017金秋冲刺训练营杯联赛模拟大奖赛Day2

T1 模拟+排序,先把n个公司贪成合法,再在剩下的天数中找最大值 注意不要统计2-t<0的天数 1 #include <cstdio> 2 #include <vector> 3 #include <iostream> 4 #include <algorithm> 5 #define ll long long 6 using namespace std; 7 long long n,m,s,k,e,t,sz,j,flag=0,ans=0,cnt[200

NOIP2017金秋冲刺训练营杯联赛模拟大奖赛Day1

前言:昨天晚上没睡好,导致今天早上起来头疼,于是睡了一多个小时,本来不想比赛了,但是发现第一题的做法实在是太显而易见,于是就愉快的AC了 T1 很简单的一道线段树问题 天天去哪吃 题目大意 小天在第i天去了第x[i]号餐厅吃饭,并且在接下来的n/2天内都不能再去这个餐厅去吃饭了,$x[i]=(a*x[i-1]+b*x[i-2]+k)\%n$ (k是能使x[i]合法的最小值,即x[i]在x[i-n/2~i-1]中没有出现过) 输入 n,m,a,b,x[1],x[2] 输出 x[3],x[4]--x

【前行】◇第3站◇ 国庆训练营&#183;OI制模拟赛

[第3站] 国庆训练营·OI制模拟赛Ⅰ 怀着冲刺提高组400的愿望来到这个very small but very interesting 的训练营QwQ 在北大dalao的带领下开始了第一场OI模拟赛[炸心态ヽ(*.>Д<)o゜] ? 简单总结 感觉非常爆炸…… 第一题还好,一眼看出结论题,所以开始打表……没想到只打出来了一种情况(为什么全是特殊情况),然后就凉了. 第二题就开始崩溃了.首先画图思考了大概20分钟……然后发现想不出正解,就开始想要骗分.看了看数据阶梯,发现自己好像只能做前1/3

团队项目冲刺第二轮——第一天

今天是第二轮团队冲刺的第一天,上次的团队成果其实并不让人满意,而且在后期出现了很大的问题.总结一下原因其实是我们只管自己独立的任务,相互之间缺乏必要的交流,其实三个人在一起编程的时间根本没有多少,大多是自己一个人.这就造成了有了想法不能与团队成员及时沟通,只能开发那些相互之间联系不大的部分,结果就是最后的整合浪费了我们大量的时间,更没时间去拓展新的功能.在这次团队冲刺中,应该极力避免上次的错误. 第二轮冲刺相对于第一次的项目要有很大的改动,所以今天我们团队重新从头到尾讨论了一下项目,明确目标之后

2017年校招全国统一模拟笔试(第二场)编程题集合-牛客网

 2017年校招全国统一模拟笔试(第二场)编程题集合-牛客网 链接:https://www.nowcoder.com/questionTerminal/276712b113c6456c8cf31c5073a4f9d7来源:牛客网 牛牛有两个字符串(可能包含空格),牛牛想找出其中最长的公共连续子串,希望你能帮助他,并输出其长度. 输入描述: 输入为两行字符串(可能包含空格),长度均小于等于50. 输出描述: 输出为一个整数,表示最长公共连续子串的长度. 输入例子: abcde abgde 输出例子

第六届华为创新杯编程大赛第二轮(2014.4.29)

第一题:外星人比数的大小 来自星星的都教授除了所有感官比地球人高出七倍,始终容颜不老以外,还拥有一项在地球人看来特别神奇的能力,他会瞬间(0.00000000000000000000001s以内)按照他的规则比较地球人熟悉的两个十进制数字的大小,他比较的规则如下:1.将要比较的两个数字分别转换成二进制数字:2.计算两个二进制数字中1的个数,个数多的数字为两者中的大者:3.负数按照其绝对值进行比较:请利用地球人发明的计算机程序逼近都教授的特异功能,实现时可以有以下约束:1.输入数据为范围在-327

JZOJ4316【NOIP2015模拟11.5】Isfind 题解

JZOJ4316 [NOIP2015模拟11.5]Isfind 题解 Description Input Output Sample Input 4 3    acbc    abc    cba    cc Sample Output Y    N    Y Data Constraint 思路: 题意要看懂,首先声明一下"子串"和"子序列"的区别,S的"子串"意思是在S中选取任意i个(0 < i <= |S|)连续字符组成的字符串

2017.9.23 NOIP2017 金秋杯系列模拟赛 day1 T1

回形遍历( calc .cpp/c/pas) 时间限制:1s内存 限制: 256MB [问题 描 述]给出一个 n*m 的棋盘,按如下方式遍历,请问(x,y)往后 z 步走到的是哪个格子. [输入]输入文件名为 calc.in.一行,包含五个整数:n,m,x,y,z[输出]输出文件名为 calc.out.输出一行,包含两个整数,表示所在格子的横纵坐标[输入输出样例] calc .in calc .out 4 5 3 0 5 2 4 [ 样例解释 ] [数据说明]对于 70%的数据,1<=n,m,