1146C Tree Diameter

题意

交互题。有一棵 \(n(n\le 100)\) 个点的树,你可以进行不超过 \(9\) 次询问,每次询问两个点集中两个不在同一点集的点的最大距离。求树的直径。

题解

GXOI2019旅行者 基本类似,二进制分组,对于每一位,编号当前位为 \(0\) 的分到一组,当前位为 \(1\) 的分到另一组。最大询问次数为 \(\log 100 = 7\)

code

#include<cstdio>
int v1[105],v2[105];
int main()
{
int T; scanf("%d",&T);
while(T--)
{
int n,ans=0; scanf("%d",&n);
for(int i=0;i<=6;++i)
{
int id1=0,id2=0;
for(int j=1;j<=n;++j) (j&(1<<i))?v1[++id1]=j:v2[++id2]=j;
if(id1&&id2)
{
printf("%d %d ",id1,id2);
for(int i=1;i<=id1;++i) printf("%d ",v1[i]);
for(int i=1;i<=id2;++i) printf("%d ",v2[i]);
puts(""); fflush(stdout);
int x; scanf("%d",&x);
if(x>ans) ans=x;
}
}
printf("-1 %d\n",ans);
fflush(stdout);
}
}

1146D Frog Jumping

题意

有一条数轴,一只青蛙在原点,可以向前跳 \(a\) 步或向后跳 \(b\) 步。

定义 \(f(x)\) 表示青蛙在 \([0,x]\) 里跳,能跳到的点数。

求 \(\sum_{i=0}^m f(i)\) 。 \(m\le 10^9, a,b\le 10^5\) 。

题解

能到达的点 \(c\) 能被表示为 \(ax-by=c\) 。

根据裴蜀定理,能到达的点一定是 \(\gcd(a,b)\) 的倍数。

但是,当 \(i<a+b\) 时,\(f(i)\) 由于跳的点不能超过 \(i\) ,有的点可能会无法跳到。故 \(f(0)\sim f(a+b)\) 的答案我们要另外计算。

我们考虑贪心的去跳,当跳的步数 \(>b\) 就减去 \(b\) 。暴力枚举 \(i\) 统计有多少个点能到达即可。

注意不要重复统计答案。

code

#include<cstdio>
int gcd(int x, int y) {
return y?gcd(y,x%y):x;
}
const int N=2e5+5;
bool vis[N];
int step[N],tot;
int main()
{
#ifndef ONLINE_JUDGE
freopen("sol.in","r",stdin);
#endif
int m,a,b;
scanf("%d%d%d",&m,&a,&b);
const int g=gcd(a,b);
long long ans=1ll*(1+m/g+1)*(m/g+1)/2ll*g-1ll*(1ll*(m/g+1)*g-m-1)*(m/g+1);
vis[step[++tot]=0]=true;
while(true)
{
++tot;
step[tot]=step[tot-1]>=b?step[tot-1]-b:step[tot-1]+a;
if(vis[step[tot]]) break;
vis[step[tot]]=true;
} --tot;
for(int i=0,j=1;i<a+b&&i<=m;++i)
{
ans-=i/g+1;
while(step[j]<=i&&j<=tot) ++j;
ans+=j-1;
}
printf("%lld",ans);
}

1146E Hot is Cold

题意

给你一个长度为 \(n\) 的序列和 \(q\) 个操作,每次操作将 \(<x_i\) 的取反或 \(>x_i\) 的数取反。求最后的序列。\(n,q\le 10^5\)

题解

对正数和负数分别维护权值线段树,然后分类讨论维护每个数是否被取反的标记。

考虑 \(>x\) :当 \(x<0\) :将绝对值 \(>x\) 的数置为负 ; 当 \(x>0\) ,将正负数绝对值 \(<-x\) 标记取反,绝对值 \(\ge -x\) 的数置为负;

\(<x\) 与上述类似。

有神仙线性做法,待补充……

code

#include<cstdio>
#include<cstring>
inline int gi()
{
char c=getchar(); int x=0,f=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
return x*f;
}
const int N=1e5+5;
int st[2][N<<2],tg[2][N<<2],rev[2][N<<2],fg[2][N<<2],a[N],n,q,m;
#define lx (x<<1)
#define rx (x<<1|1)
void pushdown(int i, int x)
{
if(tg[i][x]!=-1)
{
tg[i][lx]=tg[i][rx]=st[i][lx]=st[i][rx]=tg[i][x];
tg[i][x]=-1;
}
if(fg[i][x])
{
fg[i][lx]=fg[i][rx]=1;
rev[i][lx]=rev[i][rx]=0;
fg[i][x]=0;
}
if(rev[i][x])
{
rev[i][lx]^=1,rev[i][rx]^=1;
st[i][lx]^=1,st[i][rx]^=1;
rev[i][x]=0;
}
}
void rever(int i, int x, int l, int r, int sl, int sr)
{
if(sl>sr) return ;
if(sl<=l&&r<=sr) {
rev[i][x]^=1,st[i][x]^=1; return ;
}
pushdown(i,x);
int mid=l+r>>1;
if(sl<=mid) rever(i,lx,l,mid,sl,sr);
if(sr>mid) rever(i,rx,mid+1,r,sl,sr);
}
void update(int i, int x, int l, int r, int sl, int sr, int w)
{
if(sl>sr) return ;
if(sl<=l&&r<=sr)
{
tg[i][x]=st[i][x]=w, rev[i][x]=0, fg[i][x]=1;
return ;
}
pushdown(i,x);
int mid=l+r>>1;
if(sl<=mid) update(i,lx,l,mid,sl,sr,w);
if(sr>mid) update(i,rx,mid+1,r,sl,sr,w);
}
int qry(int i, int x, int l, int r, int s)
{
if(l==r) return st[i][x];
pushdown(i,x);
int mid=l+r>>1;
return (s<=mid?qry(i,lx,l,mid,s):qry(i,rx,mid+1,r,s));
}
int main()
{
n=gi(),q=gi();
for(int i=1;i<=n;++i)
{
a[i]=gi();
if(a[i]>m) m=a[i];
if(-a[i]>m) m=-a[i];
}
memset(tg,-1,sizeof(tg));
while(q--)
{
char s[2]; scanf("%s",s);
int x=gi();
if(s[0]=='>')
{
if(x>0)
{
update(0,1,1,m,x+1,m,0);
update(1,1,1,m,x+1,m,1);
}
else
{
rever(0,1,1,m,1,-x-1);
update(0,1,1,m,-x,m,0);
rever(1,1,1,m,1,-x-1);
update(1,1,1,m,-x,m,1);
}
}
else
{
if(x<0)
{
update(0,1,1,m,-x+1,m,1);
update(1,1,1,m,-x+1,m,0);
}
else
{
rever(0,1,1,m,1,x-1);
update(0,1,1,m,x,m,1);
rever(1,1,1,m,1,x-1);
update(1,1,1,m,x,m,0);
}
}
}
for(int i=1;i<=n;++i)
{
if(a[i]==0) printf("0 ");
else if(a[i]<0) printf("%d ",a[i]*(qry(0,1,1,m,-a[i])?-1:1));
else printf("%d ",a[i]*(qry(1,1,1,m,a[i])?-1:1));
}
}

1146F Leaf Partition

题意

给你一棵 \(n\) 个节点的树,将叶子节点划分成若干个集合,使得每个集合的虚树互不相交。求划分方案数。

\(n\le 2\cdot 10^5\) 。

题解

\(f(u,0)\) 表示 \(u\) 不属于任何集合的方案数。

\(f(u,1)\) 表示 \(u\) 连通了 \(1\) 个子节点。显然,当前节点必须要连通到上面的集合。

\(f(u,2)\) 表示 \(u\) 连通了 \(2\) 个以上的子节点。

这样,对于子节点 \(v\) ,将其分到不同集合的方案数为 \(f(v,0)+f(v,2)\) ,设为 \(x\) ;将其分到同一集合的方案数为 \(f(v,1)+f(v,2)\) ,设为 \(y\) 。

这样就不难得出转移:

\[\begin{cases}
f'(u,0)=f(u,0)\times x\\
f'(u,1)=f(u,0)\times y+f(u,1)\times x \\
f'(u,2)=f(u,1)\times y+f(u,2)\times (x+y)
\end{cases}
\]

code

#include<cstdio>
inline int gi()
{
char c; int x=0;
for(;c<'0'||c>'9';c=getchar());
for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0';
return x;
}
const int N=200005,Mod=998244353;
int f[N][3],head[N],nxt[N],to[N],n;
void addedge(int u, int v, int now) {
nxt[now]=head[u], head[u]=now, to[now]=v;
}
#define mul(x,y) (1ll*x*y%Mod)
void dfs(int u)
{
if(!head[u]) f[u][2]=1;
else f[u][0]=1;
for(int e=head[u];e;e=nxt[e])
{
int& v=to[e];
dfs(v);
int x=(f[v][0]+f[v][2])%Mod,y=(f[v][1]+f[v][2])%Mod;
int f0=mul(f[u][0],x);
int f1=(mul(f[u][0],y)+mul(f[u][1],x))%Mod;
int f2=(mul(f[u][1],y)+mul(f[u][2],(x+y)%Mod))%Mod;
f[u][0]=f0,f[u][1]=f1,f[u][2]=f2;
}
}
int main()
{
n=gi();
for(int i=2;i<=n;++i)
addedge(gi(),i,i-1);
dfs(1);
printf("%d",(f[1][0]+f[1][2])%Mod);
}

Codeforces Forethought Future Cup Elimination Round 选做的更多相关文章

  1. CF1146 Forethought Future Cup Elimination Round Tutorial

    CF1146 Forethought Future Cup Elimination Round Tutorial 叮,守夜冠军卡 https://codeforces.com/blog/entry/6 ...

  2. 【CF1146】Forethought Future Cup - Elimination Round

    Forethought Future Cup - Elimination Round 窝也不知道这是个啥比赛QwQ A. Love "A" 给你一个串,你可以删去若干个元素,使得最 ...

  3. Forethought Future Cup - Elimination Round

    A:签到. #include<bits/stdc++.h> using namespace std; #define ll long long char getc(){char c=get ...

  4. Forethought Future Cup - Elimination Round D 贡献 + 推公式 + 最短路 + 贪心

    https://codeforces.com/contest/1146/problem/D 题意 有一只青蛙,一开始在0位置上,每次可以向前跳a,或者向后跳b,定义\(f(x)\)为青蛙在不跳出区间[ ...

  5. Forethought Future Cup - Elimination Round C 二分 + 交互(求树的直径)

    https://codeforces.com/contest/1146/problem/C 题意 一颗大小为n的树,每次可以询问两个集合,返回两个集合中的点的最大距离,9次询问之内得出树的直径 题解 ...

  6. Codeforces Round #557 Div. 1 based on Forethought Future Cup - Final Round

    A:开场就读错题.读对了之后也没啥好说的. #include<bits/stdc++.h> using namespace std; #define ll long long #defin ...

  7. Forethought Future Cup - Final Round (Onsite Finalists Only) C. Thanos Nim 题解(博弈+思维)

    题目链接 题目大意 给你n堆石子(n为偶数),两个人玩游戏,每次选取n/2堆不为0的石子,然后从这n/2堆石子中丢掉一些石子(每一堆丢弃的石子数量可以不一样,但不能为0),若这次操作中没有n/2堆不为 ...

  8. [codeforces Mail.Ru Cup 2018 Round 3][B Divide Candies ][思维+数学]

    https://codeforces.com/contest/1056/problem/B 题意:输入n,m    求((a*a)+(b*b))%m==0的(a,b)种数(1<=a,b<= ...

  9. [codeforces Mail.Ru Cup 2018 Round 1 D][ xor 操作]

    http://codeforces.com/contest/1054/problem/D 题目大意:一个序列a1 a2...an,可以对若干个元素进行取反,使所得的新序列异或和为0的区间个数最多. 题 ...

随机推荐

  1. Java基础知识笔记第四章:类和对象

      编程语言的几个发展阶段 面向机器语言 面向过程语言 面向对象语言:封装.继承.多态 类 类声明 class Person{ ....... } class 植物{ ....... } 类体 类使用 ...

  2. div display 常用属性

    none:元素不被显示. block:元素将显示为块级元素,此元素前后会带有换行符. inline:行内元素(即一个挨着一个,都在同一行按从左至右的顺序显示,不单独占一行). 参考: http://w ...

  3. nginx 书籍

    1.<实战nginx> 2.<深入理解nginx> 3.nginx开发从入门到精通 http://tengine.taobao.org/book/ 4.Nginx源码学习,配置 ...

  4. Codeforces 1304D. Shortest and Longest LIS

    根据题目,我们可以找最短的LIS和最长的LIS,找最短LIS时,可以将每一个increase序列分成一组,从左到右将最大的还未选择的数字填写进去,不同组之间一定不会存在s[i]<s[j]的情况, ...

  5. 搭建springboot的ssm(spring + springmvc + mybatis)的maven项目

    最终项目目录结构 创建过程 1.创建开关SpringBootApplication 为了创建快速.我们使用idea自带的创建springboot来创建结构,当然创建普通的web项目也是可以的.(使用e ...

  6. kafka-console-consumer接收不到flume推送过来的消息

    原因和解决方法:需要先启动kafka,再启动flume,两者启动有先后顺序.

  7. Jquery - ajax url路径问题

    Jquery - ajax url路径问题 2016年04月26日 09:59:27 yuxuac 阅读数 32308    版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...

  8. Backbone.js 历史&文档

    历史: 0.1.0版本产生于  ‘— Oct 13, 2010 — Docs’ 文档: https://www.html.cn/doc/backbone/#changelog

  9. Day1-E-BZOJ1293

    Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩 ...

  10. SpringBoot 入门demo

    创建SpringBoot项目方式一 (1)新建maven项目,不使用骨架. 使用maven管理依赖就行了,不必使用骨架(模板). (2)在pom.xml中添加 <!--springboot核心. ...