题意:

给一个计算器,有一系列计算步骤,只有加,乘,幂三种运算。

有一种查询操作:查询初始值为\(x\)的时候,最终运算结果模\(29393\)的值。

有一种修改操作:可以修改第\(p\)个运算的运算符和运算数。

分析:

分解一下,\(29393=7 \times 13 \times 17 \times 19\)。

所以我们可以维护\(4\)棵线段树,区间维护的信息就是初始值为\(x\)经过这段区间最终得到的值。

然后就用中国剩余定理整合一下。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 50000 + 10;
const int maxnode = maxn * 4; const int prime[] = { 7, 13, 17, 19 }; int val[4][20][maxnode];
int n, m;
char op[maxn], tmp[5];
int x[maxn]; int pow_mod(int a, int b, int mod) {
int ans = 1;
while(b) {
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
} int calc(int a, char op, int b, int mod) {
if(op == '+') return ((a + b) % mod);
if(op == '*') return a * b % mod;
return pow_mod(a, b, mod);
} void pushup(int o) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < prime[i]; j++) {
int t = val[i][j][o<<1];
val[i][j][o] = val[i][t][o<<1|1];
}
} void build(int o, int L, int R) {
if(L == R) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < prime[i]; j++)
val[i][j][o] = calc(j, op[L], x[L], prime[i]);
return;
}
int M = (L + R) / 2;
build(o<<1, L, M);
build(o<<1|1, M+1, R);
pushup(o);
} void update(int o, int L, int R, int p) {
if(L == R) {
for(int i = 0; i < 4; i++)
for(int j = 0; j < prime[i]; j++)
val[i][j][o] = calc(j, op[p], x[p], prime[i]);
return;
}
int M = (L + R) / 2;
if(p <= M) update(o<<1, L, M, p);
else update(o<<1|1, M+1, R, p);
pushup(o);
} void gcd(int a, int b, int& d, int& x, int& y) {
if(!b) { d = a; x = 1; y = 0; }
else { gcd(b, a%b, d, y, x); y -= x*(a/b); }
} int a[4];
int CRT() {
int M = 29393, d, y, x = 0;
for(int i = 0; i < 4; i++) {
int w = M / prime[i];
gcd(prime[i], w, d, d, y);
x = (x + y*w*a[i]) % M;
}
return (x+M)%M;
} int main()
{
int T; scanf("%d", &T);
for(int kase = 1; kase <= T; kase++) {
printf("Case #%d:\n", kase);
scanf("%d%d", &n, &m); getchar();
for(int i = 1; i <= n; i++) {
scanf("%c%d", op + i, x + i);
getchar();
}
build(1, 1, n); while(m--) {
int cmd, p;
scanf("%d%d", &cmd, &p);
if(cmd == 1) {
for(int i = 0; i < 4; i++)
a[i] = val[i][p%prime[i]][1];
printf("%d\n", CRT());
} else {
getchar();
scanf("%c%d", op + p, x + p);
update(1, 1, n, p);
}
}
} return 0;
}

HDU 5238 Calculator 线段树 中国剩余定理的更多相关文章

  1. hdu 5446 Unknown Treasure 卢卡斯+中国剩余定理

    Unknown Treasure Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  2. HDU 5446 Unknown Treasure Lucas+中国剩余定理

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5446 Unknown Treasure 问题描述 On the way to the next se ...

  3. hdu 3579 Hello Kiki 不互质的中国剩余定理

    Hello Kiki Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  4. 《孙子算经》之"物不知数"题:中国剩余定理

    1.<孙子算经>之"物不知数"题 今有物不知其数,三三数之剩二,五五数之剩七,七七数之剩二,问物几何? 2.中国剩余定理 定义: 设 a,b,m 都是整数.  如果 m ...

  5. POJ 1006 中国剩余定理

    #include <cstdio> int main() { // freopen("in.txt","r",stdin); ; while(sca ...

  6. [TCO 2012 Round 3A Level3] CowsMooing (数论,中国剩余定理,同余方程)

    题目:http://community.topcoder.com/stat?c=problem_statement&pm=12083 这道题还是挺耐想的(至少对我来说是这样).开始时我只会60 ...

  7. poj1006中国剩余定理

    Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 103506   Accepted: 31995 Des ...

  8. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  9. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

随机推荐

  1. Java中的Serializable接口和transient关键字

    Java中的Serializable接口和transient关键字 Table of Contents 1. 向memcached中放数据时遇到NotSerializableException异常 2 ...

  2. 解释器模式和php实现

    解释器模式: 给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子. 角色: 环境角色:定义解释规则的全局信息. 抽象解释器::定义了部分解释具体实现,封装了 ...

  3. .net framework MVC 下 Hangfire使用,时区,权限

    安装 NuGet 上有几个可用的Hangfire 的软件包.如果在ASP.NET应用程序中安装HangFire,并使用Sql Server作为存储器,那么请在Package Manager Conso ...

  4. Kendo MVVM (一) 概述

    Kendo MVVM (一) 概述 Model View ViewModel (MVVM)  是开发人员经常使用的一种设计模式,以实现数据模型(Model)和视图(View)的分离.MVVM 中的 V ...

  5. SQL查找TCar表中同一辆车前后两条记录的CarId,两条记录中有多个字段值一样

    查询同一个表中某一字段值相同的记录 select * from 表名 where 字段 in(select 字段 from 表名 group by 字段 having count(1)>1) s ...

  6. LayUI 完美兼容Vue.js

    <div id="app"> <form class="layui-form" action=""> <div ...

  7. BZOJ 4563: [Haoi2016]放棋子

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 389  Solved: 248[Submit][Status][Discuss] Descriptio ...

  8. [VC]关于ocx控件的自己编写的dll问题

    要是无法删除c:windows/cownloadprogrames下的文件时可以关掉所有的浏览器,然后在internate----程序---管理 加载项里 先把那个加载项 更新一下,或者禁用一下,或者 ...

  9. Ubuntu下手动安装NextCloud

    安装环境:阿里云VPS Ubuntu 16.04   一. 安装Apache2 sudo apt-get install apache2 安装完成后,浏览器访问http://your ip/,出现It ...

  10. 2018.4.10 Ubuntu cat命令解答、用法

    cat命令是linux下的一个文本输出命令,通常是用于观看某个文件的内容的: cat主要有三大功能: 1.一次显示整个文件. $ cat filename 2.从键盘创建一个文件. $ cat > ...