题目出处:Calculator

简要题意:

你有一个确定的函数,f(x)=+...*...^...,其中共有n个操作,从左到右依次计算。

共有m次询问,我们每次询问,1.会修改f(x)中的操作;2.输出f(x)%29393

分析:

分解29393可以得到7*13*17*19,这几个数都很小,很容易预处理!

于是我们可以将一个f(x)%29393分成四个小方程

我们令 a1=f(x)%7; a2=f(x)%13; a3=f(x)%17; a4=f(x)%19。

那么由中国剩余定理,可以得到模29393意义下的唯一解

虽说CRT求得的,是所有正整数解的最小解,

但是,由上图我们可以知道,如果我们最终的答案要模上29393,那么CRT求得的答案就是唯一解。

接下来,我们只需要能够快速求得这四个数,即可用CRT求得答案。

由于这4个模数都很小,我们可以提前预处理出 当x小于模数时的f(x)的值

我们可以用线段树来实现函数功能!

tr[p].val[i][j] = tr[rs].val[i][tr[ls].val[i][j]];

其中val[i][j]表示:处理第i个模数,输入的x值为j

由于我们的计算是从左到右依次计算,所以父亲节点的val值,为当“输入值为左儿子x的返回值时”的右儿子的返回值。

当我们要修改函数时,只需要从叶子节点开始修改,一步一步推到根节点即可。

最后我们的a1,a2,a3,a4分别为根节点处的val[1][x],val[2][x],val[3][x],val[4][x]

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define LL long long
#define int long long
const int N=5e4+5;
inline int ksm(int x, int y, const int pp)
{
x %= pp;
y %= (pp-1);
int ret = 1;
while(y)
{
if(y&1) ret = ret*x%pp;
x=x*x%pp;
y>>=1;
}
return ret;
}
const LL chu[5]={7, 13, 17, 19};
const LL MOD = 29393;
struct segment{int a, b, val[5][20];}tr[N<<2];
void build(const int p, const int l, const int r)
{
tr[p].a=l; tr[p].b=r;
if(l != r)
{
int mid=(l+r)>>1, ls=p<<1, rs=p<<1|1;
build(ls, l, mid);
build(rs, mid+1, r);
for(re i=0;i<4;++i)
for(re j=0;j<chu[i];++j)
tr[p].val[i][j] = tr[rs].val[i][tr[ls].val[i][j]];
}
else
{
int ty, x;char ch;
scanf("%c%lld",&ch,&x);
if(ch=='+')ty=0;else if(ch=='*')ty=1;else ty=2;
getchar();
for(re i=0;i<4;++i)
{
for(re j=0;j<chu[i];++j)
{
if(ty == 0) tr[p].val[i][j] = (j+x)%chu[i];
if(ty == 1) tr[p].val[i][j] = j*x%chu[i];
if(ty == 2) tr[p].val[i][j] = ksm(j, x, chu[i]);
}
}
}
}
void modi(const int p, const int pos, const int x, const int ty)
{
if(tr[p].a == pos && pos == tr[p].b)
{
for(re i=0;i<4;++i)
{
for(re j=0;j<chu[i];++j)
{
if(ty == 0) tr[p].val[i][j] = ((j+x)%chu[i]+chu[i])%chu[i];
if(ty == 1) tr[p].val[i][j] = j*x%chu[i];
if(ty == 2) tr[p].val[i][j] = ksm(j, x, chu[i]);
}
}
return;
}
int mid=(tr[p].a+tr[p].b)>>1, ls=p<<1, rs=p<<1|1;
if(pos <= mid) modi(ls, pos, x, ty);
else modi(rs, pos, x, ty); for(re i=0;i<4;++i)
for(re j=0;j<chu[i];++j)
tr[p].val[i][j] = tr[rs].val[i][tr[ls].val[i][j]];
}
inline LL getans(const int pp)
{
LL ret=0;
for(re i=0;i<4;++i)
{
int Mi=MOD/chu[i];
int t=ksm(Mi,chu[i]-2,chu[i]);
ret=(ret+tr[1].val[i][pp%chu[i]]*Mi*(t%chu[i]))%MOD;
}
return (ret+MOD) % MOD;
}
int n, m;
inline void work()
{
scanf("%lld%lld",&n,&m);
getchar();
build(1, 1, n);
for(re i=1;i<=m;++i)
{
int op, x, y, t;char ch;
scanf("%lld",&op);
if(op == 1)
{
scanf("%lld",&x);
getchar();
printf("%lld\n", getans(x));
}
else
{
scanf("%lld",&x);
getchar();
scanf("%c%lld",&ch,&y);
if(ch=='+')t=0;else if(ch=='*')t=1;else t=2;
modi(1, x, y, t);
}
}
}
signed main()
{
int T; scanf("%lld",&T);
for(re h=1;h<=T;++h)
{
printf("Case #%lld:\n", h);
work();
}
}

“我不怕千万人阻拦,只怕自己投降”----《倔强》五月天

热身训练1 Calculator的更多相关文章

  1. 数位dp & 热身训练7

    数位dp 数位dp是一种计数用的dp,一般就是要统计一段区间$[L,R]$内,满足一定条件的数的个数,或者各个数位的个数. 数位dp使得暴力枚举变为满足一定状态的记忆化,更加优秀. 数位dp常常会考虑 ...

  2. 热身训练4 Article

    Article 在这个学期即将结束时,DRD开始写他的最后一篇文章. DRD使用著名的Macrohard的软件World来写他的文章. 不幸的是,这个软件相当不稳定,它总是崩溃. DRD需要在他的文章 ...

  3. 热身训练4 Eighty seven

    Eighty seven 简要题意: n个卡片,其中第i个卡片的数值为$a[i]$.一共q次询问,每次询问将删去其中3个卡片(可能删除若干相同的卡片)后,问能否选出10个卡片,数值之和等于87. n≤ ...

  4. 热身训练2 The All-purpose Zero

    The All-purpose Zero 简要题意:  长度为n的数组,每个数字为S[i],$0$是一种很神奇的数字,你想要的,它都可以变! 问这个序列的最长上升子序列长度为多少? 分析: 我们将除了 ...

  5. 热身训练3 Palindrome

    Palindrome 简要题意:  我们有一个字符串S,字符串的长度不超过500000. 求满足S[i]=S[2n−i]=S[2n+i−2](1≤i≤n)(n≥2)的子串个数.  分析: 我们能通过简 ...

  6. 热身训练2 GCD

    题目描述 简要题意:  n个数字,a1,a2,...,an m次询问(l,r),每次询问需回答 1.gcd(al,al+1,al+2,...,ar);2.gcd(ax,ax+1,ax+2,...,ay ...

  7. 热身训练2 Another Meaning

    题目来源 简要题意: 众所周知,在许多情况下,一个词语有两种意思.比如"hehe",不仅意味着"hehe",还意味着"excuse me". ...

  8. 热身训练1 ping ping ping

    点此进入 题意: 一棵树,n+1 个节点,以0号节点为根,给出端点(a,b),节点a到节点b的路径上,至少有一个点是"坏掉的",求"坏掉的点"最少 分析: St ...

  9. 热身训练1 Problem B. Harvest of Apples

    http://acm.hdu.edu.cn/showproblem.php?pid=6333 题意: 求 C(0,n)+C(1,n)+...+C(m,n) 分析: 这道题,我们令s(m,n) = C( ...

随机推荐

  1. Mybatis-基本学习(上)

    目录 Mybatis mybatis开始 -----环境准备 一.简介 1.什么是MyBatis 2.持久化 3.持久层 4.为什么需要Mybatis? 二.第一个Mybatis程序 1.搭建环境 1 ...

  2. git换行符自动转换导致整个文件被修改的解决方案

    不少开发者可能遇到过这个问题:从git上拉取服务端代码,然后只修改了一处地方,准备提交时,用diff软件查看,却发现整个文件都被修改了.这是git自动转换换行符导致的问题. 原因 不同操作系统使用的换 ...

  3. Ubuntu 引导修复

    Ubuntu 引导修复 前言 最近还在看 Docker 的教程,看到了"跨宿主机网络通信"的一节,于是想到去 Ubuntu 中 实践一番.结果发现 Ubuntu 进不去了.由于考虑 ...

  4. 求 10000 以内 n 的阶乘

    求 10000以内 n 的阶乘. 输入格式 只有一行输入,整数 n(0≤n≤10000) 输出格式 一行,即 n!的值. 输出时每行末尾的多余空格,不影响答案正确性 样例输入 100 样例输出 933 ...

  5. STM32L0系列EEPROM中结构体的读取

    在STM32L0中操作EEPROM本来参考了上篇操作FLASH的方法,多多少少都有些问题.我觉得可能是结构体在转换成其他变量的时候出了问题. 比如下面这段代码,在Windows上可以正常运行(使用g+ ...

  6. win10系统安装jdk

    应用程序形式 文件包形式 环境变量配置 https://www.cnblogs.com/gz9218/p/2ae083861f6749899b1b800faabe1c17.html

  7. 获取系统版本,判断是windows还是Linux

    package com.foresee.zxpt.common.utils; import java.util.Properties; /** * 获取系统版本 * @author GZ * */ p ...

  8. english note(6.2 to 5.30)

    notes 6.2 to 5.30  http://www.51voa.com/VOA_Special_English/suicide-rates-among-young-americans-on-t ...

  9. P6295-有标号 DAG 计数【多项式求逆,多项式ln】

    正题 题目链接:https://www.luogu.com.cn/problem/P6295 题目大意 求所有\(n\)个点的弱联通\(DAG\)数量. \(1\leq n\leq 10^5\) 解题 ...

  10. Mysql集群搭建(多实例、主从)

    1 MySQL多实例 一 .MySQL多实例介绍 1.什么是MySQL多实例 MySQL多实例就是在一台机器上开启多个不同的服务端口(如:3306,3307,3308),运行多个MySQL服务进程,通 ...