某线段树

打模拟赛的时候不知道区间该维护什么东西使其变得可合并,然后就放着了

赛后看了题解才知道这个题维护的是映射关系,感觉也是十分的厉害

考虑一个算式a+4(mod7)=ba + 4 \pmod{7} = b

我们发现来(mod7)\pmod{7}的同余系中,会有以下对应关系

a=0123456b=4560123a = 0\;1\;2\;3\;4\;5\;6 \\b = 4\;5\;6\;0\;1\;2\;3

其实这就是一个映射

具体的,保存这个映射可以直接开一个数组a[7],其中a[i]=(i+4)(mod7)a[7],其中a[i] = (i+4) \pmod{7}


我们现在已经能把一个算式对应成一个映射了,那么如果我们能计算出两个映射的复合,就可以用线段树解决本题了,不妨设f(x),g(x)f(x),g(x)是我们需要复合的映射

那么复合的结果就是g(f(x))g(f(x))

:一个xx过来经过ff变成了cc,然后cc进到了gg里面去出来就是xx经过这个复合的映射的结果


理论基础大概就这些,但是如果直接做的话空间复杂度是O(29393×n×4)O(29393\times n\times 4)

显然是吃不消的

如果能注意到这题的modmod不是1e9+71e9+7,1e9+71e9+7,而是一个奇怪的数

而且不是素数,29393=7×13×17×1929393 =7 \times 13 \times 17 \times 19

四个不相同的素数的乘积,是不是很巧合

聪明的你有没有想到用中国剩余定理来减少运算量呢?

用CRT优化之后,这个题的空间复杂度变成了O((7+13+17+19)×n×4)O((7+13+17+19)\times n\times 4)

已经可以解决这个问题了o(` • ~ • ′。)o


最后一点是关于代码的

因为需要四个线段树,为了方便我定义了结构体


其它地方如果有不懂的,希望给窝留言,窝会更新一发博客

那么就酱(⊙v⊙)

#include<bits/stdc++.h>
using namespace std;const int maxn = 51234;#define root 1,1,n
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define Now int o,int l,int r
#define Mid int m = (l+r)/2int pmod(int a,int n,int mod){a %= mod;int ret = 1;while(n){if(n&1) (ret *= a) %= mod;(a *= a) %= mod;n>>=1;}return ret;
}struct segtree{int v[maxn*4][30];int mod;void clean(int *s){for(int i=0;i<mod;i++){s[i] = i;}}void init(int val){mod = val;}void add(int o){int l = o<<1,r = o<<1|1;for(int i=0;i<mod;i++){v[o][i] = v[r][ v[l][i] ];}}void update(int o,char oper,int num){ //[+,*,^]int *s = v[o];if(oper=='+') for(int i=0;i<mod;i++) s[i] = (i+num)%mod;if(oper=='*') for(int i=0;i<mod;i++) s[i] = (i*num)%mod;if(oper=='^') for(int i=0;i<mod;i++) s[i] = pmod(i,num,mod);}void update(Now,int pos,char oper,int num){if(l==r){update(o,oper,num);return;}Mid;if(pos <= m) update(lson,pos,oper,num);else update(rson,pos,oper,num);add(o);}int query(int x){x %= mod;return v[1][x];}
};struct allseg{segtree sg[4];int v[4]={7,13,17,19};int coe[4] = {25194,27132,17290,18564};int M = 29393;allseg(){for(int i=0;i<4;i++)sg[i].init(v[i]);}int n;void init(int N){n = N;}void update(int pos,char oper,int x){for(int i=0;i<4;i++)sg[i].update(root,pos,oper,x);}int query(int x){int ans = 0;for(int i=0;i<4;i++){(ans += coe[i] * sg[i].query(x) )%= M;}int ret = 0;return ans;}
};allseg S;int getnum(char *s){int ret = 0;while(*s){ret = ret * 10 + (*s-'0');s++;}return ret;
}int main()
{int T,icase = 1;scanf("%d",&T);int n,m;while(T-- && ~scanf("%d %d",&n,&m)){S.init(n);char op[10];for(int i=1;i<=n;i++){scanf("%s",op);S.update(i,*op,getnum(op+1));}int ord,x;printf("Case #%d:\n",icase++);while(m--){scanf("%d",&ord);if(ord == 1){scanf("%d",&x);printf("%d\n",S.query(x));}else{scanf("%d",&x);scanf("%s",op);S.update(x,*op,getnum(op+1));}}}return 0;
}

hdu 5238 Calculator相关推荐

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

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

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

    题意: 有加,乘,次方3种运算,初始值为x,给定运算式. 现在有2种操作: 第一种:告诉你x的值,求答案模29393. 第二种:更改某个位置的运算. 解析: 线段树维护值域的问题,但是那个操作并不能简 ...

  3. HDU 5238 Calculator【线段树】

    其实这题真是不好想啊 首先,我们观察到29393不是一个质数,通过质分解我们得到 29393=7∗13∗17∗19 29393=7*13*17*19于是就可以想到中国剩余定理,将数给分解了再求模方程. ...

  4. hdu 5238 Calculator(线段树+CRT)

    题意:有加,乘,次方3种运算,初始值为x,给定运算式,2种操作,第一种:告诉你x的值,求答案模29393.第二种:更改某个位置的运算. 做法:乍一看就像线段树,但是那个操作并不能简单的合并,所以我们得 ...

  5. hdu 5238 Calculator(线段树+中国剩余定理)

    非常巧的一个题. 运算过多,肯定得用数据结构维护一些东西,这里要维护的是映射关系,运算的本质其实就是函数,也就是映射. 但是答案对29393取模,对0-29393的数维护映射在空间上和时间上都是撑不住 ...

  6. 【HDU】5238 Calculator 【中国剩余定理+线段树】

    传送门:[HDU]5238 Calculator 题目分析: 模数可以拆成四个小素数:7,13,17,19. 这样我们可以分别对这几个素数跑答案,最后中国剩余定理搞一下就好.中间我们用线段树,保存每个 ...

  7. HDU 5238 线段树+数论

    原题:http://acm.hdu.edu.cn/showproblem.php?pid=5238. 题解:给你长度为n的操作序列,和m组操作求每组操作的模29393的值.这道题直接显然是没有前途的, ...

  8. HDU - 5238(剩余定理)

    题意: 给出一个计算的序列,包含{+,*,^}三种运算.给出两种操作,1是给出初始值,求按照序列计算的答案,2是修改序列中某个位置的数和运算符. 描述: 问题最后要把结果对29393去模,把模拆分为7 ...

  9. 2015 上海邀请赛c题 calculator hdu5238

    http://acm.hdu.edu.cn/showproblem.php?pid=5238 题目很不错,注意到29393=7*13*17*19,只要计算出答案模这四个数的值即可通过中国剩余定理解出答 ...

最新文章

  1. 优秀工程师至关重要的一项技能,你解锁了吗?
  2. Maven项目下HttpServletRequest 或 HttpServletResponse需引用的依赖包
  3. java中lambda表达式的应用
  4. 《大话数据结构》第9章 排序 9.6 希尔排序(下)
  5. C++ 类模板语法初步01
  6. php 接受 amp,php中amp;amp;和||的用法
  7. python如何设置字体大小_[Python Basic]如何设置 Python 的运行环境
  8. BeautifulSoap库入门
  9. C++中回调(CallBack)的使用方法
  10. VMware Workstation 14 Pro 安装 Windows Server 2003(完)
  11. 看图纸V3.2.1正式版[看图纸正式版下载]
  12. echarts官网demo
  13. oracle 设置输出显示,oracle输出语句
  14. java 数据抓取 动态获得cookies里变动的属性_Java爬取CSDN博客遇到setCookie问题
  15. pdf签名无效解决办法_2020最新房屋租赁合同范本(8种无效)
  16. html里表格做斜线表头,word表格斜线_Word2010怎么绘制斜线表头-太平洋IT百科
  17. Chrome下载文件,文件名出现乱码解决
  18. Spring boot快速开发Rest服务
  19. DEM数据知识介绍-数字高程模型
  20. 学习笔记——HTML实现个人简历制作

热门文章

  1. 当case when then else end 语句遇上sum或count等统计函数
  2. css实现单边斜切效果
  3. 一个屌丝程序猿的人生(九十四)
  4. mac 启动台不显示已经安装的软件图标
  5. 如何备份 WordPress 数据库
  6. solidworks显示无法连接到服务器,SOLIDWORKS Electrical解决方法:无法连接协同服务器...
  7. Alibaba Cloud - 云服务常见产品与架构
  8. 《调色师手册:电影和视频调色专业技法(第2版)》——第1章 调色的工作流程 我要为电影院(电影)、广播(电视),还是网络调色?...
  9. Golang:加密解密算法
  10. 景联文科技:手势识别如何在自动驾驶中应用,一文告诉你答案