洛谷 P8318 题解
作者:互联网
题意:
给出一个长度为 \(n\) 的操作后的序列,然后给出 \(m\) 次操作过程,每次给出操作类型 \(op\)、操作数 \(x\) 和 \(y\),求出操作前的原始序列。
在操作中,如果 \(x=y\),那么新的 \(x\) 就分别等于原始 \(x\) 的
两倍或平方。即:如果 \(op=1\),那么新的第 \(x\) 个元素就等于它的两倍;如果 \(op=2\),那么新的第 \(x\) 个元素就等于它的平方。
思路:
模拟题,但是坑点很多。
-
由于给出的是操作后的序列,所以我们在还原时需要倒序还原,例如:\(n=2\),两次操作分别是 \(op1,x1,y1\) 和 \(op2,x2,y2\)。那么我们就需要先还原 \(op2,x2,y2\) 再还原 \(op1,x1,y1\)。
-
同上,需要倒序还原,如果操作中是乘法,还原时就需要用除法,加减法同理。
-
题目中还提到 \(x=y\) 的情况。当 \(op=1\) 时,原操作是将第 \(x\) 个元素 \(×2\),那么我们在还原时就需要将它 \(÷2\);同理,当 \(op=2\) 时,原操作是将第 \(x\) 个元素变成它的平方,那么我们在还原时就要将它进行
sqrt()
。
code:
#include <bits/stdc++.h>
using namespace std;
inline long long read(){
long long s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
int n,m;
long long a[1005];
int op[1005],x[1005],y[1005];
int main(){
n=read();m=read();
for(int i=1;i<=n;i++){
a[i]=read();
}
for(int i=1;i<=m;i++){
op[i]=read();x[i]=read();y[i]=read();
}
for(int i=m;i>=1;i--){
if(op[i]==1){
if(x[i]==y[i]){
a[x[i]]/=2;
}
else{
a[x[i]]-=a[y[i]];
}
}
else{
if(x[i]==y[i]){
a[x[i]]=sqrt(a[x[i]]);
}
else{
a[x[i]]/=a[y[i]];
}
}
}
for(int i=1;i<=n;i++){
printf("%lld ",a[i]);
}
return 0;
}
标签:ch,洛谷,题解,P8318,long,else,还原,操作,op 来源: https://www.cnblogs.com/liu-black/p/p8318-tijie.html