hdu5238(中国剩余定理+线段树)
来源:互联网 发布:防盗网络应用 编辑:程序博客网 时间:2024/05/16 10:29
hdu5238
题目链接
题意是对于一个数字x,进行一次有n个运算操作的的运算,如*5 +6 ^3,就是对x先*5再+6 再3次幂,然后输出最后的结果对29393取模的答案.
然后接下来有m次操作,有两种,一种是可以把某个运算符修改掉.另一种是把给x赋一个值
直接模拟的话复杂度肯定是受不了的.然后查了题解发现可以和中国剩余定理结合起来,中国剩余定理大概就是,当我们知道一个x对几个互质的pi取模的结果ai,(ai,pi已知)我们可以通过中国剩余定理求出x.
然后我们把29393分解质因数7 13 17 19 ,4个质因数都不是很大,于是我们想到对于给定的x我们先分别对这4个质数取模后经过一系列运算得到的结果再用中国剩余定理合并.
接下来就是修改运算符的,我们考虑用线段树来维护,tree[i][j][rt]存的是x模第i个素数意义下等于j时经过一系列运算后的值,那么tree[i][j][rt] = tree[i][ tree[i][j][rt<<1] ][rt<<1|1] (这个地方不太好理解 , 仔细看看大概也能明白 , 就是j经过左子树的一系列运算后得到的数字再放到右子树里运算后得到的数字 ) 然后修改的时候就是直接单点修改
#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<set>#include<map>#include<time.h>#include<cstdio>#include<vector>#include<list>#include<stack>#include<queue>#include<iostream>#include<stdlib.h>using namespace std;#define LONG long longconst LONG INF= 0X3f3f3f3f;const int MOD=29393;const double PI=acos(-1.0);#define clrI(x) memset(x,-1,sizeof(x))#define clr0(x) memset(x,0,sizeof x)#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10#define lson l , mid , rt<< 1#define rson mid + 1 ,r , (rt<<1)+1#define root 1, m , 1const int MAXN = 50000+ 50 ;int mod[5] ;int tree[4][20][MAXN<<2] ;int n , m ;int table [4][20][30000] ;struct OP{ char c ; int x ;}num[MAXN];void Push_Up(int rt){ for(int i = 0 ; i< 4 ; ++i) { for(int j = 0 ; j < mod[i] ; ++j) tree[i][j][rt] = tree[i][ tree[i][j][rt<<1] ][rt<<1|1] ; }}int exgcd(int a,int b,int &x,int &y){ if(b==0) { x=1; y=0; return a; } int r=exgcd(b,a%b,x,y); int t=x; x=y; y=t-a/b*y; return r;}int CRT(int *a){ int ans = 0 ; int x , y; for(int i = 0 ;i < 4 ; ++ i) { exgcd(MOD /mod[i] ,mod[i] , x , y ) ;; ans = ( ans + a[i] * ( MOD / mod[i] ) *x ) %MOD; } return (ans + MOD)%MOD ;}void Build(int l ,int r ,int rt){ if( l == r ) { for(int i = 0 ; i < 4; ++i) { for(int j = 0 ;j < mod[i] ; ++ j) if(num[l].c == '+') tree[i][j][rt] = (j +num[l].x)%mod[i] ; else if(num[l].c == '*') tree[i][j][rt] = (j * num[l].x) % mod[i] ; else tree[i][j][rt] = (table[i][j][num[l].x]) % mod[i] ; } return ; } int mid = (l + r) /2 ; Build(l , mid , rt<<1) ; Build(mid + 1, r , rt<<1|1 ) ; Push_Up(rt) ;}void Update(int rt ,int t){ for(int i = 0 ; i < 4 ; ++ i) { for(int j =0 ; j < mod[i] ; ++j) if(num[t].c == '+') tree[i][j][rt] = (j + num[t].x) % mod[i] ; else if(num[t].c == '*') tree[i][j][rt] = (j * num[t].x) % mod[i] ; else tree[i][j][rt] = table[i][j][num[t].x] % mod[i] ; } rt >>= 1; while(rt ) { Push_Up(rt ) ; rt >>= 1; }}int Find(int l ,int r , int rt,int x){ if(l ==r && l ==x ) return rt ; int mid = (l + r) / 2 ; if( x<= mid) return Find(l , mid, rt<<1 , x) ; else return Find(mid+1 , r , rt << 1|1 , x) ;}int Q_pow(int a, int b , int c ){ int res = 1; while(b ) { if(b&1) res = (res * a) %c ; a = (a *a)%c ; b /= 2 ; } return res%c;}int main(){ mod[0] = 7 , mod[1] = 13 , mod[2] = 17 ; mod[3] = 19 ; for(int i = 0 ; i< 4 ; ++ i) for(int j = 0 ; j < mod[i] ; ++j) for(int k = 0 ; k < MOD ; ++k) table[i][j][k] = Q_pow(j, k,mod[i]) ; int T; cin >>T; int ca= 0 ; while(T -- ) { cin >> n >> m; char c ;int x; for(int i = 1 ; i <= n ; ++ i) getchar () , scanf("%c%d",&num[i].c ,&num[i].x) ; Build(1 , n ,1) ; int op ; int p ; int a[10] ; printf("Case #%d:\n",++ca) ; while(m -- ) { scanf("%d",&op) ; if(op == 1) { scanf("%d",&x) ; for(int i = 0 ;i < 4; ++i) a[i] = tree[i][x%mod[i]][1] ; int res = CRT(a); cout<<res<<endl; } else { scanf("%d",&p) ; getchar() ; scanf("%c%d",&c,&x) ; num[p].c = c , num[p].x = x ; int tt = Find(1 , n ,1 , p ) ; Update( tt , p ) ; } } } return 0 ;}
阅读全文
1 0
- hdu5238(中国剩余定理+线段树)
- 【HDU】5238 Calculator 【中国剩余定理+线段树】
- HDU 5238 Calculator(中国剩余定理+线段树)
- HDU 5238 Calculator(线段树+中国剩余定理)
- hdu 5238 Calculator(线段树+中国剩余定理)
- hdu - 5238 Calculator(线段树+中国剩余定理)线段树好题
- 中国剩余定理模版【中国剩余定理】
- 中国剩余定理
- 中国剩余定理
- 中国剩余定理
- 中国剩余定理
- 中国剩余定理
- 中国剩余定理
- 中国剩余定理
- 中国剩余定理
- 数论-中国剩余定理
- 中国剩余定理
- 中国剩余定理
- Android数据库框架-----ORMLite 的基本用法
- KMP算法
- Spring Data自定义Repository接口方法定义规范
- [leetcode]7. Reverse Integer@Java解题报告
- Java基础之对象与类
- hdu5238(中国剩余定理+线段树)
- UE4之材质参数的使用
- python018 Python3 输入和输出
- 【Linux】01_腾讯云Ubuntu安装及远程访问MySql
- JXNU暑期选拔赛题解
- Tomcat 服务器Session管理深入剖析-附带源代码分析
- 逗号运算符花絮
- DEM 接边软件(不同源的DEM平缓过渡)
- Dubbo 管控台如何链接zookeeper集群