HDU-5238 Calculator
题目描述
给定一个关于 \(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\),我们有:
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的更多相关文章
- hdu 5238 Calculator(线段树,中国剩余定理¥)
Calculator Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tot ...
- HDU 5238 Calculator 线段树 中国剩余定理
题意: 给一个计算器,有一系列计算步骤,只有加,乘,幂三种运算. 有一种查询操作:查询初始值为\(x\)的时候,最终运算结果模\(29393\)的值. 有一种修改操作:可以修改第\(p\)个运算的运算 ...
- 华农oj 2192: hzk又在打人【CRT合并/待补】
2192: hzk又在打人 Time Limit: 12 Sec Memory Limit: 512 MB Submit: 52 Solved: 1 [Submit][Status][Web Boar ...
- HDU 5475(2015 ICPC上海站网络赛)--- An easy problem(线段树点修改)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5475 Problem Description One day, a useless calculato ...
- hdu 5475 An easy problem(暴力 || 线段树区间单点更新)
http://acm.hdu.edu.cn/showproblem.php?pid=5475 An easy problem Time Limit: 8000/5000 MS (Java/Others ...
- HDU 5475 An easy problem 线段树
An easy problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 1335 Basically Speaking(进制转换)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1335 Problem Description The Really Neato Calculator ...
- HDU 1221 Rectangle and Circle 考虑很多情况,good题
http://acm.hdu.edu.cn/showproblem.php?pid=1221 114 92 31 95 13 96 3 这题只需要判断圆和矩形是否相交,然后在里面是不算相交的. 那么就 ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- [LeetCode] Basic Calculator II 基本计算器之二
Implement a basic calculator to evaluate a simple expression string. The expression string contains ...
随机推荐
- java jsp基础介绍
1 Jsp基础 1.1 Jsp介绍 JSP(全称Java Server Pages)是一种web动态网页开发技术,通过标签和指令完成用户界面开发和交互操作.它使用J ...
- HearthBuddy Plugin编写遇到的问题
错误1 赋值问题 貌似编译器版本有点低,无法识别C#的高级语法糖 属性的初始值,必须是public bool IsEnabled { get{return true;} } 不能写成public bo ...
- websphere部署不能发布war文件,提示“配置库中已存在应用程序
碰上这种问题, 要是全删除与war相关配置文件,要么按网上教程,一点点搜下面的文件中包含的相关文件: $WAS_HOME/profiles/AppSrv01/config/cells/...cell/ ...
- ccf 201612-4 压缩编码(DP)(100)
ccf 201612-4 压缩编码 问题分析: 解决本问题,首先需要知道哈夫曼编码.参见:哈夫曼编码_百度百科. 这是一个编码问题,似乎可以用哈夫曼编码来解决,但是略有不同的地方在于“每个字符的编码按 ...
- CentOS6 Zabbix-Agent2.0安装脚本
#! /bin/bash ##################################### #-----------------------------------# #------zabb ...
- python 装饰器 (test = submit(test))
两层的装饰器,这里对于register不需要进行输入 usename, passwd = 'alex', 'abc123' def register(func): def wrapper(*args, ...
- Vue踩坑系列
前言 前端开发对于vue的使用已经越来越多,它的优点就不做介绍了, 本篇是我对vue使用过程中遇到的问题中做的一些总结,帮助大家踩坑.如果喜欢的话可以点波赞,或者关注一下,希望本文可以帮到大家!!! ...
- DFA和NFA的区别
正则表达式引擎分成两类,一类称为DFA(确定性有穷自动机),另一类称为NFA(非确定性有穷自动机).两类引擎要顺利工作,都必须有一个正则式和一个文本串,一个捏在手里,一个吃下去.DFA捏着文本串去比较 ...
- json-lib json反序列化——日期转换
将json格式的字符串转为对象,其中key-value有将String的日期转为Date类型,怪现象就是,转出来的Date类型的值是当前的系统时间. 网上有许多答案,在反序列化之前需要注册Date解析 ...
- stm8问题记录
sprintf 错误 现象:打印不出来数字 需要包含#include<stdio.h>