题解 P4140 【奇数国 】
首先,按照题意,把前$60$个素数打出来$[2$ $-$ $281]$。
因为只有$60$个,再加上本宝宝极其懒得写线性筛于是每一个都$O(\sqrt{n})$暴力筛就好了。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int main()
{
// freopen("1.txt","w",stdout);
printf("");//格式问题,以自己爱好稍作更改。
for(int i=;i<=;i++)
{
for(int j=;j*j<=i;j++)
if(i%j==) goto rp;
printf(",%d",i),n++;
rp:;
}
return ;
}
如果我们用$prime[i]$表示第i个素数。
筛出来是这样的:
int prime[]={
,,,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,
,,,,,
,,,,,
,,,,,
,,,,,
,,,,,
,,,,,
,
};
---
之后,我们看 清点存款 操作,
问$[1,product]$里,有多少个$num$满足:
$$num*x+product*y=1$$
这,与我们 素数的性质 好像啊。
这就是 $num*x≡1$ $ $ $ $ $(mod$ $ $ $product)$
也就是 $gcd(num$ $,$ $product)$ $=$ $1$
嗯,好,问题转化成了:
求 $[1,product]$ 里,有多少个 $num$ 与 $product$ 互质。
也就是 $\varphi(product)$ 等于多少。
之后,根据欧拉函数的通式。
$$\varphi(n)=n*\prod_{p_i|n}(1-\frac{1}{p_i})=n*\prod_{p_i|n}\frac{p_i-1}{p_i}$$
看数据范围,又让 $mod$ $ $ $p$
所以,
再线性推一下逆元,
求解即可。
---
$ps:$ 如果脸黑被卡常数了的话,可以把 $[1-281]$ 的逆元打表。
大概代码是这样的:
pni[]=;
for(int i=;i<=;i++)
pni[i]=(long long)(mod-mod/i)*pni[mod%i]%mod;
---
下面,就是区间维护。
题目中说了,~~(在出题人眼里)~~他们的加法相当于我们的乘法。
我们要维护区间 $[a,b]$ 的 “和” 记为 $product$
更改的是某个点(银行)$b_{i}$ 的存款
显然的线段树保存每段区间出现的质因子。
看题面,由于最多出现$60$个质数,我们用一个 $long$ $ $ $long$ 的每一位表示一个质数,然后用或运算$xor$即可实现 “加和” 相乘操作。
然后就……
好好的写代码吧。
不过……
模数为啥不是 $19260817$ 或者是 $998244353$ 或 $64123$ 呢……
---
$ps:$ 一定要看看线段树每次的区间边上判定 $!$ $!$ $!$
本宝宝调了两天 $……$
委屈巴巴。。。
---
上代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define mod 19961993 const int prime[]={
,,,,,,,,,
,,,,,,,
,,,,,,,
,,,,,,
,,,,,
,,,,,
,,,,,
,,,,,
,,,,,
,,,,,
,
};//记录质数。 int pni[]; //线段树。
struct data{
long long sum;//区间(和)乘积
long long p;//包含哪些素数。第i个二进制位如果是1,则有prime[i]这个素数,从1开始。
}point[];
data ans;//记录查询答案。 void built(int l,int r,int o)
{
if(l==r) {point[o].sum=;point[o].p=;return ;}
int mid=(l+r)/;
built(l,mid,o*);
built(mid+,r,o*+); // printf("%d %d %d %d\n",l,r,o,mid); point[o].sum=point[o*].sum*point[o*+].sum%mod;
point[o].p=;
// printf("%d %d\n",point[o].sum,point[o].p);
} void chang(int l,int r,int o,const int t,const int k)//第t个点改为k
{
// printf("%d %d %d %d %d\n",&l,&r,&o,&t,&k);
if(l==r){
point[o].sum=k;
long long p=;
for(int i=;i<=;i++){
if((k%prime[i])==) p|=1LL<<(i-);
point[o].p=p;
}
return ;
}
int mid=(l+r)/;
if(t<=mid) chang(l,mid,o*,t,k);
else chang(mid+,r,o*+,t,k);
point[o].sum=point[o*].sum*point[o*+].sum%mod;
point[o].p=point[o*].p|point[o*+].p;
} void quest(int l,int r,int o,int l1,int r1)//查询L到R。
{
if(l1<=l&&r<=r1){
ans.sum=ans.sum*point[o].sum%mod;
ans.p|=point[o].p;
return ;
}
int mid=(l+r)/;
if(l1<=mid) quest(l,mid,o*,l1,r1);
if(mid<r1) quest(mid+,r,o*+,l1,r1);
}
// void debug()
// {
// for(int i=1;i<=100;i++)
// printf("%d %d %d\n",i,point[i].p,point[i].sum);
// } int main()
{ // freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
built(,,); pni[]=;
for(int i=;i<=;i++)
pni[i]=(long long)(mod-mod/i)*pni[mod%i]%mod;
//线性筛逆元 int tt;
scanf("%d",&tt);
while(tt--)
{
int x;scanf("%d",&x); if(x)
{
int t,k;
scanf("%d%d",&t,&k);
chang(,,,t,k);
} else
{
int l1,r1;
ans.sum=;
ans.p=;
scanf("%d%d",&l1,&r1);
quest(,,,l1,r1); long long f=ans.sum;
for(int i=;i<=;i++)//计算φ
if(ans.p&(1LL<<(i-))) f=f*(prime[i]-)%mod,f=f*pni[prime[i]]%mod;
printf("%d\n",(int)f); }
// debug();
}
return ;//程序拜拜
}
题解 P4140 【奇数国 】的更多相关文章
- Bzoj 3813 奇数国 题解 数论+线段树+状压
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 748 Solved: 425[Submit][Status][Discuss] ...
- [BZOJ 3813]奇数国
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 736 Solved: 416[Submit][Status][Discuss] ...
- 【BZOJ3813】奇数国 线段树+欧拉函数
[BZOJ3813]奇数国 Description 给定一个序列,每次改变一个位置的数,或是询问一段区间的数的乘积的phi值.每个数都可以表示成前60个质数的若干次方的乘积. Sample Input ...
- [BZOJ3813] 奇数国 - 线段树
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 912 Solved: 508[Submit][Status][Discuss] ...
- AC日记——【清华集训2014】奇数国 uoj 38
#38. [清华集训2014]奇数国 思路: 题目中的number与product不想冲: 即为number与product互素: 所以,求phi(product)即可: 除一个数等同于在模的意义下乘 ...
- 【bzoj3813】: 奇数国 数论-线段树-欧拉函数
[bzoj3813]: 奇数国 题意:给定一个序列,每个元素可以分解为最小的60个素数的形式.(x=p1^k1*p2^k2*......p60^k60)(p1=2,p2=3,…,p60=281) 支持 ...
- 【题解】L 国的战斗续之多路出击 [P2129]
[题解]L 国的战斗续之多路出击 [P2129] 传送门: \(L\) 国的战斗续之多路出击 \([P2129]\) [题目描述] 给出 \(n\) 个坐标,\(m\) 个指令,指令处理顺序应是从后往 ...
- HYSBZ - 3813 奇数国 欧拉函数+树状数组(线段树)
HYSBZ - 3813奇数国 中文题,巨苟题,巨无敌苟!!首先是关于不相冲数,也就是互质数的处理,欧拉函数是可以求出互质数,但是这里的product非常大,最小都2100000,这是不可能实现的.所 ...
- 【数论&线段树】【P4140】[清华集训2015]奇数国
Description 有一个长为 \(n\) 的序列,保证序列元素不超过 \(10^6\) 且其质因数集是前60个质数集合的子集.初始时全部都是 \(3\),有 \(m\) 次操作,要么要求支持单点 ...
随机推荐
- Access 数据库的数据类型
今天开发数据库通用组件时,做C#数据库类型与Access数据库类型的相互转化时,发现Access中“text”类型的最大长度为255,当长度超过255时,需改用“Memo”类型,但需要注意备注(Mem ...
- python学习——练习题(2)
""" 题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元 ...
- BurpSuite系列(九)----Comparer模块(比较器)
一.简介 Burp Comparer在Burp Suite中主要提供一个可视化的差异比对功能,来对比分析两次数据之间的区别.使用中的场景可能是: 1.枚举用户名过程中,对比分析登陆成功和失败时,服务器 ...
- 【知识碎片】CSS 篇
1.CSS达到截取效果 地方卡机了会计师的立法及 => 地方卡机了... max-width: 400px; overflow: hidden; white-space: nowrap; t ...
- 10-EasyNetQ之控制队列名称
EasyNetQ默认行为,当生成队列的名称时,使用消息类型名+subscription Id.例如:PartyInvitation 这个消息类型,命名空间为 EasyNetQ.Tests.Integr ...
- CXF动态客户端如何优化JaxWsDynamicClientFactory.createClient -- 慢
在CXF动态创建客户端时,如下: JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); Client ...
- linux进行Java开发环境的部署
一.前言: 今天正式向linux开发进攻了,其中遇到一些问题简单的记录一下,为之后的再次部署提供方便. 二.linux的Java8安装的两种方法: 1.源安装很简单,一个命令搞定. sudo apt- ...
- java基础之多线程五:实现Runnable的原理
实现Runnable接口的原理. 背景: 多线程的第一种实现方式是::继承Thread类, 因为我们自定义的类(MyThread)是Thread类的子类, 所以MyThread类的对象调用start( ...
- Java对象的强、软、弱和虚引用
本文介绍Java对象的强.软.弱和虚引用的概念.应用及其在UML中的表示. 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象 ...
- POJ1039几何
这道题目要求我们判断光线进入一条管道后可以抵达的最大的x坐标. 这是我做的第一道几何题目,卡了我半天.翻了不少书,才大概明白了些.既然是第一次做,就把所有今天学到的就全部写下好了. 1.如何判断平面上 ...