Codeforces 1143
Posted blogofchc1234567890
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1143相关的知识,希望对你有一定的参考价值。
1143 B
题意
给你 (n) ,计算 (f(n)=n) 的每一个数码相乘得到的结果。( (nle 10^9) )
Examples
input
390
output
216
input
7
output
7
input
1000000000
output
387420489
解
从右往左依次把每一位变成9,更新答案。
1143 C
题意
给你一棵树,有一些节点尊重它们的祖先,现在你要执行若干步,每步删除一个编号最小的点,满足它尊重它的祖先,且它的所有子节点(不是子树)尊重它。输出删除节点的序列。序列为空输出-1。( (nle 10^5) )
Examples
input
5
3 1
1 1
-1 0
2 1
3 0
output
1 2 4
input
5
-1 0
1 1
1 1
2 0
3 0
output
-1
input
8
2 1
-1 0
1 0
1 1
1 1
4 0
5 1
7 0
output
5
解
一个节点删除后不会对任何节点产生影响。
所以找到初始状态所有满足条件的节点按顺序输出即可。
1143 D
题意
给一个有 (n*k) 个点的环,环上从 (1) 开始,每 (k) 个点有一个餐厅,你每次单向移动 (L) 个点,现在不知道你的初始位置和 (L) 的值,但是知道你初始位置离最近的餐厅的距离 (a) 和你第一次移动之后离最近的餐厅的距离 (b) 。你移动若干次后能回到起点,求这个值的最小值和最大值。( (1le n,kle 100000,0le a,ble frac{k}{2}) )
Examples
input
2 3
1 1
output
1 6
input
3 2
0 0
output
1 3
input
1 10
5 3
output
5 5
解
首先我们钦定第一步时你在 (a+1) 处。
然后枚举所有可能的 (b) ,算出答案,更新。
有了第一步和第二步的位置怎么算答案?
设 (t=(第一步位置-第二步位置)\% (n*m))
我们发现走的步数为 (n*m/gcd(t,n*m)) (千万不要写成 ( ext{lcm}(t,n*m)/t) ,会爆unsigned long long)
Code
#include<bits/stdc++.h>
using namespace std;
template<typename tp>
void read(tp& x){
x=0;
char c=getchar();
bool sgn=0;
while((c<'0'||c>'9')&&c!='-')c=getchar();
if(c=='-')sgn=1,c=getchar();
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
if(sgn)x=-x;
}
template<typename tp>
void write(tp x){
if(x<0)putchar('-'),write(-x);
else{
if(x>=10)write(x/10);
putchar(x%10+'0');
}
}
typedef long long D;
D m,n,a,b;
D w(D x){return x?x:n*m;}
D gcd(D a,D b){return b==0?a:gcd(b,a%b);}
D solve(D x,D y){
D t=w((y+n*m-x)%(n*m));
D l=n*m/gcd(t,n*m);
return l;
}
int main(){
read(m),read(n),read(a),read(b);
D mi=LLONG_MAX,mx=LLONG_MIN;
for(D i=1,j=1+b,tmp;i<=m;i++,j+=n){
tmp=solve(1+a,j);
mi=min(mi,tmp);
mx=max(mx,tmp);
}
for(D i=1,j=n+1-b,tmp;i<=m;i++,j+=n){
tmp=solve(1+a,j);
mi=min(mi,tmp);
mx=max(mx,tmp);
}
write(mi),putchar(' '),write(mx);
return 0;
}
1143 E
题意
给你一个排列 (p) 和数组 (a) ,有 (t) 组询问,每次询问一个区间的子序列中是否有 (p) 的一个循环排列。( (1≤|p|,|a|,t≤2*10^5) )
Examples
input
3 6 3
2 1 3
1 2 3 1 2 3
1 5
2 6
3 5
output
110
input
2 4 3
2 1
1 1 2 2
1 2
2 3
3 4
output
010
解
处理出 (a) 中每个元素 (a[i]) 的前驱 (pre[i]) ,前驱定义为值为在排列中对应 (a[i]) 的上一个元素,且最靠近 (a[i]) 的数
(dp[i]=dp[pre[i]]+1)
我们发现形成了森林
然后需要处理出 (a[i]) 上面第 (n) 个祖先,可以用倍增,也存到一个数组 (s[i]) 中
询问时查询 ([l,r]) 区间中是否存在 (i) 使得 (s[i]>=l) ,用线段树或者其他数据结构维护。
1143 F
题意
平面上有 (n) 个点,求有多少条不同的抛物线 (y=x^2+bx+c(b,cin R)) ,满足没有点严格在其上方。( (nle 10^5) )
Examples
input
3
-1 0
0 2
1 0
output
2
input
5
1 0
1 -1
0 -1
-1 0
-1 -1
output
1
解
首先将所有点的坐标减去横坐标的平方
于是抛物线退化成了直线
用上凸包维护
注意特判两个点横坐标相同的情况
以上是关于Codeforces 1143的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #549 (Div. 2) D 数学