题目描述

给定一个关于 \(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. 编写批处理使用msbuild编译项目

    echo off ::请把此bat脚本放到以下代码路径下 并在环境变量中配置对应版本的vs编译器的值 ::vs2017如:C:\Program Files (x86)\Microsoft Visual ...

  2. PHP-过滤器-连接数据库-解析XML

    PHP 过滤器 what? PHP 过滤器用于验证和过滤来自非安全来源的数据,比如用户的输入. 验证和过滤用户输入或自定义数据是任何 Web 应用程序的重要组成部分. 设计 PHP 的过滤器扩展的目的 ...

  3. C++模板的偏特化与全特化

    模板的声明 类模板和函数模板的声明方式是一样的,在类定义/模板定义之前声明模板参数列表.例如: // 类模板 template <typename T1, typename T2> cla ...

  4. ARTS打卡计划第二周

    Algorithms: https://leetcode-cn.com/problems/3sum/ 算法是先排序,然后按照两个数和两边逼中,考虑去重. Review: https://www.inf ...

  5. (八)C语言之printf

  6. centos7 - mysql修改密码

    set password for 'root'@'localhost'=password('MyNewPass4!'); mysql5.7默认安装了密码安全检查插件(validate_password ...

  7. STL -- heap结构及算法

    STL -- heap结构及算法 heap(隐式表述,implicit representation) 1. heap概述 : vector + heap算法 heap并不归属于STL容器组件,它是个 ...

  8. JS字符串转换为JSON的方法

    1.jQuery插件支持的转换方式:  示例: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象 2.浏览 ...

  9. 小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型

    笔记 2.技术选型和学后水平     简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度,          1.IDEA JDK8 Maven SpringBoot基础 Linux 2.理 ...

  10. npm install --save 和 npm install -d的区别

    npm install -d 就是npm install --save-dev npm insatll -s 就是npm install --save 以前一直在纠结一个npm安装的包依赖管理的问题. ...