题目描述

给定一个关于 \(x\) 的表达式,形如下例:\(×4+2^3+8×6\)

按如下方法计算:\((((x×4)+2)^3+8)×6\)

运算符只有 加号,乘号,幂运算三种,给定的式子中有 \(n\)次运算。

进行 \(m\)次给定的操作:

1.表示对一个给定的 \(x\) 值,求原式的结果并对 \(29393\) 取模;

2.表示将 \(k\) 位置上的运算符和运算符后面的数字改变。完成这些操作。

Input

有多组数据。

\(1≤n,m≤50000\)

Output

对于每组数据输出答案。

Sample Input

2
5 4
*4
+2
^3
+8
*6
1 2
1 3
2 3 *5
1 3
4 3
*4
^4
+4
*10
1 1
2 3 ^4
1 1

Sample Output

Case #1:
6048
16512
468
Case #2:
2600
4107

让我们来看一下这个奇特的模数\(29393=7*13*17*19\)。

至于有什么用呢?我们先往下看。

首先,我们需要去快速的查询一个数经过这\(n\)个操作的值,同时我们需要支持快速修改的操作。

待修改的数据结构,还有区间查询我们直接就想到的线段树。

我们该如何转移呢?


对于当前区间\(L,R\),编号为\(num\),未知数为\(x\)的结果为\(F(x,L,R,num)\)。

考虑两个子区间合并。

设\(val=F(x,L,mid,num<<1|1)\),即\(x\)经过左子区间的答案。

那我们就有了\(F(x,L,R,num)=F(val,mid+1,R,num<<1|1)\)。

于是我们就可以利用线段树快速进行求解的。


我们仔细看看,模数为\(29393\),线段数对于每个小于等于模数的数都要储存答案。

空间复杂度为\(O(4*n*模数)\),时间复杂度为\(O(n*log_n*模数)\)。

无论是时间还是空间都无法承受。

现在,让我们再看一下之前所提到的\(29393\)。

我们把它分解为\(7*13*17*19\)。

我们发现,对于这\(4\)个数作为模数的时间和空间复杂度都是可以承受的。

那么设当前\(x\)经过这\(4\)个模数的答案为\(res_i\),最终答案为\(Ans\),我们有:

\[\begin{cases}
Ans=res_1\%p_1 \\
Ans=res_2\%p_2 \\
Ans=res_3\%p_3 \\
Ans=res_4\%p_4
\end{cases}
\]

我们直接利用中国剩余定理求解即可。

#include <cstdio>
#include <iostream> using namespace std; #define LL long long
#define reg register
#define clr(a,b) memset(a,b,sizeof a)
#define Mod(x) (x>=mod)&&(x-=mod)
#define abs(a) ((a)<0?-(a):(a))
#define debug(x) cerr<<#x<<"="<<x<<endl;
#define debug2(x,y) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl;
#define debug3(x,y,z) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,G,x) for(int i=(G).Head[x]; i; i=(G).Nxt[i])
#pragma GCC optimize(2) inline int Read(void) {
int res=0,f=1;
char c;
while(c=getchar(),c<48||c>57)if(c=='-')f=0;
do res=(res<<3)+(res<<1)+(c^48);
while(c=getchar(),c>=48&&c<=57);
return f?res:-res;
} template<class T>inline bool Min(T &a, T const&b) {
return a>b?a=b,1:0;
}
template<class T>inline bool Max(T &a, T const&b) {
return a<b?a=b,1:0;
}
const int N=5e4+5,M=1e5+5,Prime[]= {7,13,17,19}; bool MOP1; int A[N]; char op[N]; struct SEG {
int val[5][25][N<<2];
inline void up(int num) {
ret(i,0,4)ret(j,0,Prime[i]) {
int nxt=val[i][j][num<<1];
val[i][j][num]=val[i][nxt][num<<1|1];
}
}
inline int calc(int a,char op,int b,int mod) {
if(op=='+')return (a+b)%mod;
if(op=='*')return (a*b)%mod;
int res=1;
while(b) {
if(b&1)res=res*a%mod;
a=a*a%mod,b>>=1;
}
return res;
}
inline void build(int L,int R,int num) {
if(L==R) {
rep(i,0,3)ret(j,0,Prime[i])val[i][j][num]=calc(j,op[L],A[L],Prime[i]);
return;
}
int mid=(L+R)>>1;
build(L,mid,num<<1);
build(mid+1,R,num<<1|1);
up(num);
}
inline void update(int L,int R,int num,int pos) {
if(L==R) {
rep(i,0,3)ret(j,0,Prime[i])val[i][j][num]=calc(j,op[L],A[L],Prime[i]);
return;
}
int mid=(L+R)>>1;
if(pos<=mid)update(L,mid,num<<1,pos);
else update(mid+1,R,num<<1|1,pos);
up(num);
}
} tr; int n,res[N],mod[N],a[N],pos[N]; int Exgcd(int a, int b, int &x, int &y) {
if(!b) {
x=1,y=0;
return a;
}
int g=Exgcd(b,a%b,y,x);
y-=a/b*x;
return g;
} inline int Excrt(void) {
mod[1]=7,mod[2]=13,mod[3]=17,mod[4]=19;
int M=mod[1],ans=res[1],x,y;
rep(i,2,4) {
int g=Exgcd(M,mod[i],x,y);
x*=(res[i]-ans)/g,y=mod[i]/g,x=(x%y+y)%y;
ans=M*x+ans,M=M/g*mod[i],ans%=M;
}
int z=(ans%M+M)%M;
return z;
} bool MOP2; inline void _main(void) {
int T=Read(),Case=0;
while(T--) {
printf("Case #%d:\n",++Case);
int n,m;
scanf("%d%d",&n,&m),getchar();
char c;
rep(i,1,n)scanf("%c%d",op+i,&A[i]),getchar();
tr.build(1,n,1);
while(m--) {
int Op,pos;
scanf("%d%d",&Op,&pos);
if(Op==1) {
rep(i,0,3)res[i+1]=tr.val[i][pos%Prime[i]][1];
printf("%d\n",Excrt());
} else {
getchar(),scanf("%c%d",op+pos,&A[pos]);
tr.update(1,n,1,pos);
}
}
}
} signed main() {
_main();
return 0;
}

HDU-5238 Calculator的更多相关文章

  1. hdu 5238 Calculator(线段树,中国剩余定理¥)

    Calculator Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  2. HDU 5238 Calculator 线段树 中国剩余定理

    题意: 给一个计算器,有一系列计算步骤,只有加,乘,幂三种运算. 有一种查询操作:查询初始值为\(x\)的时候,最终运算结果模\(29393\)的值. 有一种修改操作:可以修改第\(p\)个运算的运算 ...

  3. 华农oj 2192: hzk又在打人【CRT合并/待补】

    2192: hzk又在打人 Time Limit: 12 Sec Memory Limit: 512 MB Submit: 52 Solved: 1 [Submit][Status][Web Boar ...

  4. HDU 5475(2015 ICPC上海站网络赛)--- An easy problem(线段树点修改)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5475 Problem Description One day, a useless calculato ...

  5. hdu 5475 An easy problem(暴力 || 线段树区间单点更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=5475 An easy problem Time Limit: 8000/5000 MS (Java/Others ...

  6. HDU 5475 An easy problem 线段树

    An easy problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  7. HDU 1335 Basically Speaking(进制转换)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1335 Problem Description The Really Neato Calculator ...

  8. HDU 1221 Rectangle and Circle 考虑很多情况,good题

    http://acm.hdu.edu.cn/showproblem.php?pid=1221 114 92 31 95 13 96 3 这题只需要判断圆和矩形是否相交,然后在里面是不算相交的. 那么就 ...

  9. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  10. [LeetCode] Basic Calculator II 基本计算器之二

    Implement a basic calculator to evaluate a simple expression string. The expression string contains ...

随机推荐

  1. delphi通过url下载文件

    procedure TfrmEngineerImport.btnDownloadClick(Sender: TObject);var vsql, SourceFile, DestFile, filen ...

  2. 进程间通信之管道--pipe和fifo使用

    匿名管道pipe 函数原型: #include <unistd.h> int pipe(int fildes[2]); 参数说明 fildes是我们传入的数组,也是一个传出参数.filde ...

  3. 【黑马JavaSE】1_1_11_IDEA、12_方法、13_重载

    文章目录 1_1_11_01开发工具IntelliJ IDEA 1.3 创建包.查看包的目录结构 1.5 字体设置(File->Settings->Editor->Font) 1.6 ...

  4. python:科学计数法转化为浮点型数据

    def as_num(x): y='{:.5f}'.format(x) # 5f表示保留5位小数点的float型 return(y) 实验一下 as_num(1.2e-4) In [3]:as_num ...

  5. [GIT]提交后版本恢复

    如果在回退以后又想再次回到之前的版本,可以用relog查看commit id,再使用reset设置.   1.执行 relog 后:   展示的最前面的部分就是commit id,后面会用来作为恢复的 ...

  6. koa 基础(二十)nodejs 操作mongodb数据库 --- 新增数据

    1.app.js /** * nodejs 操作mongodb数据库 * 1.安装 操作mongodb * cnpm install mongodb --save * 2.引入 mongodb 下面的 ...

  7. [Java]算术表达式组建二叉树,再由二叉树得到算式的后序和中序表达式

    Entry类: package com.hy; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...

  8. Constructor、Method、Field 源码阅读

    AnnotatedElement /** * AnnotatedElement 接口表示目前正在此 VM 中运行的应用程序的一个已注解元素[类.方法.属性]. * 该接口允许反射性地读取注解.此接口中 ...

  9. C代码调用Java代码

    C代码调用Java代码应用场景 复用已经存在的java代码 c语言需要给java一些通知 c代码不方便实现的逻辑(界面) 反射 //1.加载类字节码 Class clazz = Demo.class. ...

  10. python|爬虫东宫小说

    2k小说网爬取最近大火的<东宫>小说,借鉴之前看过的一段代码,修改之后,进行简单爬取. from urllib import requestfrom bs4 import Beautifu ...