HDU 3071-Gcd Lcm game-线段树+素因子分解-[解题报告]HOJ
Gcd & Lcm game
问题描述 :
To be a friend of this gay, you have been invented by him to play this interesting game with him. Of course, you need to work out the answers faster than him to get a free lunch, He he…
输入:
For each test case.The first line is the length of sequence n, and the number of queries q. (1<=n, q<=100000) The second line has n numbers, they are the initial n numbers of the sequence a1,a2, …,an,
From the third line to the q+2 line are the description of the q operations. They are the one of the two forms:
L k1 k2 p; you need to work out the value after mod p of lcm of the subsequence from k1 to k2, inclusive. (1<=k1<=k2<=n)
G k1 k2 p; you need to work out the value after mod p of gcd of the subsequence from k1 to k2, inclusive. (1<=k1<=k2<=n)
C k v; the k-th number of the sequence has been changed to v.
You can assume that all the numbers before and after the replacement are positive and no larger than 100.
输出:
For each test case.The first line is the length of sequence n, and the number of queries q. (1<=n, q<=100000) The second line has n numbers, they are the initial n numbers of the sequence a1,a2, …,an,
From the third line to the q+2 line are the description of the q operations. They are the one of the two forms:
L k1 k2 p; you need to work out the value after mod p of lcm of the subsequence from k1 to k2, inclusive. (1<=k1<=k2<=n)
G k1 k2 p; you need to work out the value after mod p of gcd of the subsequence from k1 to k2, inclusive. (1<=k1<=k2<=n)
C k v; the k-th number of the sequence has been changed to v.
You can assume that all the numbers before and after the replacement are positive and no larger than 100.
样例输入:
6 4 1 2 4 5 6 3 L 2 5 17 G 4 6 4 C 4 9 G 4 6 4
样例输出:
9 1 3
一道还不错的题目,解法:线段树+位压缩
题意:
给定一个长度为n的序列m次操作,操作的种类一共有三种
- 查询
- L :查询一个区间的所有的数的最小公倍数modp
- G :查询一个区间的所有的数的最大公约数modp
- 修改
- C :将给定位置的值修改成x
分析:
首先我们注意一下数据的范围,保证数据不超过100,那么很明显素因子特别少一共只有25个,我们可以用线段树维护一下对应素因子的最大值与最小值。更新的话就是单点更新。由于时间比较紧,我们需要把所有的数压到一个int中去。
对任意x<=100 其因子个数情况如下:
int prime[]={ 2, 3, 5, 7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97}; int dpos[]={28,25,23,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; //max num 7 4 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 //bit 3 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 //tot bit 3+3+2+2+21*1=31 // 0000 0000 0000 0000 0000 0000 0000 0000 // | | | | // 2 3 5 7
所以,可以用一个32位的int数字表示x对应的各因子数
#define _min(x,y) ((x)<(y)?(x):(y)) #define _max(x,y) ((x)>(y)?(x):(y)) inline int min(int x,int y){return _min(x&0x70000000,y&0x70000000)|_min(x&0x0e000000,y&0x0e000000)|_min(x&0x01800000,y&0x01800000)|_min(x&0x00600000,y&0x00600000)|((x&0x001fffff)&(y&0x001fffff)); } inline int max(int x,int y){return _max(x&0x70000000,y&0x70000000)|_max(x&0x0e000000,y&0x0e000000)|_max(x&0x01800000,y&0x01800000)|_max(x&0x00600000,y&0x00600000)|((x&0x001fffff)|(y&0x001fffff)); }
自定义比较函数,即分别计算x与y的每个因子出现的最大与最小次数。
然后就是裸的单点更新,成段求最值的线段树了
001
|
#include<cstdio>
|
002
|
003
|
const int maxn=444444;
|
004
|
int prime[]={ 2, 3, 5, 7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
|
005
|
int dpos[]={28,25,23,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
|
006
|
int a[]={1,2,4,8,16,32,64};
|
007
|
int b[]={1,3,9,27,81};
|
008
|
int c[]={1,5,25};
|
009
|
int d[]={1,7,49};
|
010
|
011
|
#define lson l,mid,lrt
|
012
|
#define rson mid+1,r,rrt
|
013
|
#define mid ((l+r)>>1)
|
014
|
#define lrt rt<<1
|
015
|
#define rrt rt<<1|1
|
016
|
017
|
int MAX[maxn],MIN[maxn];
|
018
|
inline int turn( int x){
|
019
|
int cnt,y=0;
|
020
|
for ( int i=0;i<25&&x>1;i++){
|
021
|
for (cnt=0;x%prime[i]==0;x/=prime[i]) cnt++;
|
022
|
y|=cnt<<dpos[i];
|
023
|
}
|
024
|
return y;
|
025
|
}
|
026
|
inline int back( int x, int p)
|
027
|
{
|
028
|
long long y=1;
|
029
|
int k=x>>dpos[0];y=y*a[k]%p;x^=k<<dpos[0];
|
030
|
k=x>>dpos[1];y=y*b[k]%p;x^=k<<dpos[1];
|
031
|
k=x>>dpos[2];y=y*c[k]%p;x^=k<<dpos[2];
|
032
|
k=x>>dpos[3];y=y*d[k]%p;x^=k<<dpos[3];
|
033
|
for ( int i=4;i<25;i++)
|
034
|
if (x&(1<<dpos[i])) y=y*prime[i]%p;
|
035
|
return y;
|
036
|
}
|
037
|
#define _min(x,y) ((x)<(y)?(x):(y))
|
038
|
#define _max(x,y) ((x)>(y)?(x):(y))
|
039
|
inline int min( int x, int y){
|
040
|
return _min(x&0x70000000,y&0x70000000)|_min(x&0x0e000000,y&0x0e000000)|_min(x&0x01800000,y&0x01800000)|_min(x&0x00600000,y&0x00600000)|((x&0x001fffff)&(y&0x001fffff));
|
041
|
}
|
042
|
inline int max( int x, int y){
|
043
|
return _max(x&0x70000000,y&0x70000000)|_max(x&0x0e000000,y&0x0e000000)|_max(x&0x01800000,y&0x01800000)|_max(x&0x00600000,y&0x00600000)|((x&0x001fffff)|(y&0x001fffff));
|
044
|
}
|
045
|
046
|
047
|
inline void pushup( int rt){
|
048
|
MAX[rt]=max(MAX[lrt],MAX[rrt]);
|
049
|
MIN[rt]=min(MIN[lrt],MIN[rrt]);
|
050
|
}
|
051
|
void build( int l, int r, int rt){
|
052
|
if (l==r){
|
053
|
int x; scanf ( "%d" ,&x);
|
054
|
MIN[rt]=MAX[rt]=turn(x);
|
055
|
return ;
|
056
|
}
|
057
|
build(lson);build(rson);
|
058
|
pushup(rt);
|
059
|
}
|
060
|
void update( int k, int x, int l, int r, int rt){
|
061
|
if (l==r){
|
062
|
MAX[rt]=MIN[rt]=turn(x);
|
063
|
return ;
|
064
|
}
|
065
|
if (k<=mid) update(k,x,lson);
|
066
|
else update(k,x,rson);
|
067
|
pushup(rt);
|
068
|
}
|
069
|
int query_max( int s, int t, int l, int r, int rt){
|
070
|
if (s<=l&&t>=r) return MAX[rt];
|
071
|
int ret=0;
|
072
|
if (s<=mid) ret=max(ret,query_max(s,t,lson));
|
073
|
if (t>mid) ret=max(ret,query_max(s,t,rson));
|
074
|
return ret;
|
075
|
}
|
076
|
int query_min( int s, int t, int l, int r, int rt){
|
077
|
if (s<=l&&t>=r) return MIN[rt];
|
078
|
int ret=0x7fffffff;
|
079
|
if (s<=mid) ret=min(ret,query_min(s,t,lson));
|
080
|
if (t>mid) ret=min(ret,query_min(s,t,rson));
|
081
|
return ret;
|
082
|
}
|
083
|
int main()
|
084
|
{
|
085
|
int n,q;
|
086
|
while ( scanf ( "%d%d" ,&n,&q)!=EOF){
|
087
|
build(1,n,1);
|
088
|
char s[2];
|
089
|
while (q--){
|
090
|
scanf ( "%s" ,s);
|
091
|
if (s[0]== 'C' ){
|
092
|
int k,v;
|
093
|
scanf ( "%d%d" ,&k,&v);
|
094
|
update(k,v,1,n,1);
|
095
|
}
|
096
|
else if (s[0]== 'L' ){
|
097
|
int k1,k2,p;
|
098
|
scanf ( "%d%d%d" ,&k1,&k2,&p);
|
099
|
int x=query_max(k1,k2,1,n,1);
|
100
|
printf ( "%u\n" ,back(x,p));
|
101
|
}
|
102
|
else {
|
103
|
int k1,k2,p;
|
104
|
scanf ( "%d%d%d" ,&k1,&k2,&p);
|
105
|
int x=query_min(k1,k2,1,n,1);
|
106
|
printf ( "%u\n" ,back(x,p));
|
107
|
}
|
108
|
}
|
109
|
}
|
110
|
return 0;
|
111
|
}
|
参考:http://blog.csdn.net/wxfwxf328/article/details/7479874
HDU 3071-Gcd Lcm game-线段树+素因子分解-[解题报告]HOJ相关推荐
- 洛谷 P3373 【模板】线段树 2 解题报告
P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上\(x\) 2.将某区间每一个数加上\(x\) 3.求出某区间每一个数的和 输入输出格式 ...
- HDU 1166 敌兵布阵(线段树:点更新,区间求和)
HDU 1166 敌兵布阵(线段树:点更新,区间求和) http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意: 给你n个整数,然后给你多条命令,每条命令如 ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- 2019CCPC网络赛 1002 HDU 6703(权值线段树)
2019CCPC网络赛 1002 HDU 6703(权值线段树) 思路:用权值线段树存题目给的数据后,2操作就是求权值线段树中大于等于k的部分中,靠近左端点的第一个大于r的值(这个求出来的只是原序列中 ...
- HDU - 5381 The sum of gcd(莫队/线段树区间合并)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,再给出 mmm 次询问,每次询问需要回答区间 [L,R][L,R][L,R] 内所有子区间的 gcdgcdgcd 之和.更具体的,对于询问 ...
- 2014多校第四场1006 || HDU 4902 Nice boat (线段树 区间更新)
题目链接 题意 : 给你n个初值,然后进行两种操作,第一种操作是将(L,R)这一区间上所有的数变成x,第二种操作是将(L,R)这一区间上所有大于x的数a[i]变成gcd(x,a[i]).输出最后n个数 ...
- HDU 6070 Dirt Ratio(线段树、二分)
http://acm.hdu.edu.cn/showproblem.php?pid=6070 题解 首先不难看出错误率是单调的,那么我们可以直接二分答案x,某个区间的错误率=区间数的种类cnt/区间长 ...
- hdu 5692 Snacks(dfs序+线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5692 解题思路:这道题是树节点的点权更新,而且涉及到子树,常用的思路是利用dfs序,用线段树来对区间进 ...
- HDU 6089 Rikka with Terrorist (线段树)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6089 题解 这波强行维护搞得我很懵逼... 扫描线,只考虑每个点能走到左上方(不包括正上方,但包括正左 ...
最新文章
- 上传文件大小的配置Webcong
- php实现文件夹管理器,php实现文件管理与基础功能操作
- Keras保存和载入训练好的模型和参数
- CentOs7安装apache以及遇到的问题
- Android安全笔记-进程间通信基本概念(intent、bundle、Parcelable、parcel)
- springboot2.0 fastjson 日期格式化不生效解决
- python爬取知乎live_Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)...
- 一招教你数据仓库如何高效批量导入与更新数据
- web项目中保存emoji到mysql数据库
- java jdk的作用_Java JDK环境配置及配置作用说明
- QQ输入法新功能设计文档
- 开4核后用哪个软件测试稳定性,测试CPU的稳定性的方法
- 陈强《高级计量经济学及stata应用》相关数据
- 360无线wifi路由器连接到服务器,把360无线路由器设置为二级路由器 | 192路由网...
- Tableau权限设置
- SOHO如何做外贸独立站?
- freeRTOS学习 — 消息邮箱
- php ffmpeg 转码mp4,PHP+FFMPEG实现将视频自动转码成H264标准Mp4文件
- un ange frappe a ma porte
- 3DMAX中旋转楼梯的做法