第一行,两个数n,m,表示步骤数和操作数。 接下来一行,描述n个步骤,每个步骤由一个运算符和一个参数构成。步骤之间由一个或多个空格分隔。 接下来m行,描述m个操作,有以下两种格式 1 x 其中x是一个整数,表示将x代入公式计算 2 x p 其中x是一个整数,p是一个步骤(格式同上),表示将第x个步骤替换为p
输出
对于每个1类型操作,输出一行,表示觉醒力量的属性和威力,空格分隔。
样例输入
4 5
+1 *4 -9 ^7
1 2
1 1
2 1 -4
1 2
1 1
样例输出
Electric 2187
Fairy 46188
Fight 4403
Rock 5325
提示
【数据规模和约定】对于10%的数据,n,m<=5000另有20%的数据,没有2类操作对于80%的数据,n,m<=30000奇数编号测试点没有^操作。对于100%的数据,n,m<=100000,2操作中1<=x<=n,运算中运算符为+-*^之一,所有其他整数均小于2^31。solution先考虑第一问输入一个数,输出经过运算后%17的结果,支持修改运算符用线段树维护,另ans[i]表示把i放入(L,R)的结果,i为0~16tree[k].ans[i]=tree[k*2+1].ans[tree[k*2].ans[i]];这样就可以了第二问可以发现 46189=11*13*17*19通过构造同余方程可用CRT解出然而我写了暴力。。#include
#include
#include
#include
#include
#include
#define maxn 100005
using namespace std;
int n,m,Mod[4]={11,13,17,19},t1,t2;
struct node{
int v,op;
}s[maxn];
char ch[20];
struct no{
int l,r,v[4][20];
}tree[maxn*4];
const char sh[17][10]={
"Fight","Flying","Poison","Ground","Rock","Bug","Ghost","Steel","Fire",
"Water","Grass","Electric","Psychic","Ice","Dragon","Dark","Fairy"
};
int val(int k,node a,int mod){
long long ans;
if(a.op==1)ans=(k+a.v)%mod;
if(a.op==2)ans=(k-a.v)%mod;
if(a.op==3)ans=(k*(a.v%mod))%mod;
if(a.op==4){
long long p=k;ans=1;
while(a.v){
if(a.v&1)ans*=p;
p*=p;p%=mod;ans%=mod,a.v/=2;
}
}
ans=(ans%mod+mod)%mod;
return (int)ans;
}
void wh(int k){
for(int i=0;i<4;i++){
for(int j=0;j<20;j++)
tree[k].v[i][j]=tree[k*2+1].v[i][tree[k*2].v[i][j]];
}
}
void build(int k,int L,int R){
tree[k].l=L,tree[k].r=R;
if(L==R){
for(int i=0;i<4;i++){
for(int j=0;j<20;j++)
tree[k].v[i][j]=val(j,s[L],Mod[i]);
}
return;
}
int mid=L+R>>1;
build(k*2,L,mid);build(k*2+1,mid+1,R);
wh(k);
}
void outp(int k){
int x=tree[1].v[2][k%17];
printf("%s ",sh[x]);
int ans[4];
for(int i=0;i<4;i++){
ans[i]=tree[1].v[i][(k%Mod[i])];
}
for(int i=ans[3];i<=46188;i+=19){
bool fl=0;
for(int j=0;j<3;j++){
if((i%Mod[j])!=ans[j]){
fl=1;break;
}
}
if(!fl){printf("%d
",i);return;}
}
}
node get(){
node fs;
scanf(" %s",ch);
int len=strlen(ch);
if(ch[0]=='+')fs.op=1;
if(ch[0]=='-')fs.op=2;
if(ch[0]=='*')fs.op=3;
if(ch[0]=='^')fs.op=4;
int vv=0;
for(int j=1;j>1;
if(pl<=mid)lian(k*2,pl,a);
else lian(k*2+1,pl,a);
wh(k);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)s[i]=get();
build(1,1,n);
for(int i=1;i<=m;i++){
int t;scanf("%d",&t);
if(t==1){
scanf("%d",&t1);
outp(t1);
}
else {
int pl;scanf("%d",&pl);
node xx;
xx=get();
lian(1,pl,xx);
}
}
return 0;
}