BUPT Summer Journey #test7 E
来源:互联网 发布:ubuntu 安装 交换分区 编辑:程序博客网 时间:2024/04/30 16:10
446. 大神题
时间限制 2000 ms 内存限制 65536 KB
题目描述
小弱最近在研究质数,他认为两个数互质是一个好性质。现在hiyot大神为了考考他学习的成果,给了他长度为n的整数序列a1、a2 .. an。同时给了他下面了两种操作:
操作一:"1 l r", 先求出区间[l, r]的所有数的gcd, 再计算[2,m]中有多少个数与gcd互质。
操作二: "2 p x", 把a[p]数值替换为x( 1 <= x <= 1000)
小弱是弱渣,但是如果你做出来了,他会认可你为大神,请你帮他算算。
输入格式
有多组数据。
每组数据以n( 1<=n<=10000), m(2<=m<=1000000), q(1<=q<=10000)开头。接下来一行有n(1 <= ai <= 1000)个数。最后q行每行有三个数,对应于一个操作。
输出格式
对每一个查询输出对应个数(如果区间gcd为1,则输出-1)。
输入样例
5 10 102 2 3 3 51 1 41 3 31 5 51 1 22 3 22 4 21 1 42 3 102 4 101 3 4
输出样例
-16 7443
思路:其实这道题来说的话gcd是容易更新的,难就在处理互质上。有两种处理方式,一种是用容斥原理,另外一种是分区间然后统计。由于时限为2000ms都可以过。
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<vector>#define maxn 20000//#define LOCALusing namespace std;int n,m,q,result,gcd[4*maxn],ans[maxn],a[maxn];int prime[]={0,2,3,5,7,11,13,17,19,23,29,31};vector<int> g[2000];void Init(){ for(int i=2;i<=1000;i++) { g[i].clear();int temp=i; for(int j=1;j<=11;j++) if(temp%prime[j]==0) { while(temp%prime[j]==0)temp/=prime[j]; g[i].push_back(prime[j]); } if(temp!=1)g[i].push_back(temp); }}int solve(int a,int m){ int sz=g[a].size(); int ret=0; if(sz==1) ret=m-m/g[a][0]; else if(sz==2) ret=m-m/g[a][0]-m/g[a][1]+m/(g[a][0]*g[a][1]); else if(sz==3){ int a1=g[a][0],a2=g[a][1],a3=g[a][2]; ret=m-m/a1-m/a2-m/a3+m/(a1*a2)+m/(a1*a3)+m/(a2*a3)-m/(a1*a2*a3); } else if(sz==4){ int a1=g[a][0],a2=g[a][1],a3=g[a][2],a4=g[a][3]; ret=m-m/a1-m/a2-m/a3-m/a4+m/(a1*a2)+m/(a1*a3)+m/(a1*a4)+m/(a2*a3)+m/(a2*a4)+m/(a3*a4)-m/(a1*a2*a3)-m/(a1*a2*a4)-m/(a1*a3*a4)-m/(a2*a3*a4)+m/(a1*a2*a3*a4); } else if(sz==5){ int a1=g[a][0], a2=g[a][1], a3=g[a][2], a4=g[a][3], a5=g[a][4]; ret=m-m/a1-m/a2-m/a3-m/a4-m/a5+m/(a1*a2)+m/(a1*a3)+m/(a1*a4)+m/(a1*a5)+m/(a2*a3)+m/(a2*a4)+m/(a2*a5)+m/(a3*a4)+m/(a3*a5)+m/(a4*a5)-m/(a1*a2*a3)-m/(a1*a2*a4)-m/(a1*a2*a5)-m/(a1*a3*a4)-m/(a1*a3*a5)-m/(a1*a4*a5)-m/(a2*a3*a4)-m/(a2*a3*a5)-m/(a2*a4*a5)-m/(a3*a4*a5)+m/(a1*a2*a3*a4)+m/(a1*a2*a3*a5)+m/(a1*a2*a4*a5)+m/(a1*a3*a4*a5)+m/(a2*a3*a4*a5)-m/(a1*a2*a3*a4*a5); } return ret-1;}int Gcd(int a,int b){ if(b==0)return a; return Gcd(b,a%b);}void build(int l,int r,int Ind){ if(l==r){gcd[Ind]=a[l];return;} int mid=(l+r)>>1; build(l,mid,Ind<<1); build(mid+1,r,(Ind<<1)+1); gcd[Ind]=Gcd(gcd[Ind<<1],gcd[(Ind<<1)+1]);}void Modify(int a,int l,int r,int Ind,int d){ //printf("Up l=%d r=%d\n",l,r); if(l==r&&l==a){gcd[Ind]=d;return;} int mid=(l+r)>>1; if(a<=mid)Modify(a,l,mid,Ind<<1,d); else Modify(a,mid+1,r,(Ind<<1)+1,d); gcd[Ind]=Gcd(gcd[Ind<<1],gcd[(Ind<<1)+1]); //printf("Down l=%d r=%d gcd[%d]=%d\n",l,r,Ind,gcd[Ind]);}void query(int a,int b,int l,int r,int Ind){ //printf("Up a=%d b=%d l=%d r=%d ",a,b,l,r);printf("result=%d\n",result); if(a<=l&&r<=b){result=Gcd(result,gcd[Ind]);return;} int mid=(l+r)>>1; if(a<=mid)query(a,b,l,mid,Ind<<1); if(mid<b)query(a,b,mid+1,r,(Ind<<1)+1); gcd[Ind]=Gcd(gcd[Ind<<1],gcd[(Ind<<1)+1]); //printf("Down a=%d b=%d l=%d r=%d gcd[%d]=%d\n",a,b,l,r,Ind,gcd[Ind]);printf("result=%d\n",result);}void Cal(){ ans[1]=-1; for(int i=2;i<=1000;i++) { int cnt=0,k=m/i,r=m%i; for(int j=1;j<i;j++)if(Gcd(i,j)==1)cnt++; ans[i]=cnt*k-1; for(int j=1;j<=r;j++)if(Gcd(i,j)==1)ans[i]++; } /*ans[1]=-1; for(int i=2;i<=1000;i++)//可能出现的gcd值 { int cnt=0,pr=m/i,la=m%i; for(int j=1;j<i;j++)if(Gcd(i,j)==1)cnt++; ans[i]=cnt*pr-1; for(int j=1;j<=la;j++)if(Gcd(i,j)==1)ans[i]++; }*/}int main(){ #ifdef LOCAL freopen("input.txt","r",stdin); #endif // LOCALf while(scanf("%d%d%d",&n,&m,&q)==3) { int kind,l,r,x,v; for(int i=1;i<=n;i++)scanf("%d",&a[i]); build(1,n,1); Init(); //for(int i=1;i<=10;i++)printf("gcd[%d]=%d\n",i,gcd[i]); //cout<<query(1,2,1,n,1)<<endl; //Cal(); for(int i=1;i<=q;i++) { scanf("%d",&kind); if(kind==1) { scanf("%d%d",&l,&r); result=a[r];query(l,r,1,n,1); if(result==1)printf("-1\n"); else { int ret=solve(result,m); printf("%d\n",ret); } } if(kind==2){scanf("%d%d",&x,&v);a[x]=v;Modify(x,1,n,1,v);} } } return 0;}
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<vector>#define maxn 20000//#define LOCALusing namespace std;int n,m,q,result,gcd[4*maxn],ans[maxn],a[maxn];int prime[]={0,2,3,5,7,11,13,17,19,23,29,31};vector<int> g[2000];template<class T>inline bool read(T &n){ T x=0,tmp=1;char c=getchar(); while((c<'0'||c>'9')&&c!='-'&&c!=EOF)c=getchar(); if(c==EOF)return false; if(c=='-')c=getchar(),tmp=-1; while(c>='0'&&c<='9')x*=10,x+=(c-'0'),c=getchar(); n=x*tmp;return true;}template<class T>inline void write(T n){ if(n<0){putchar('-');n=-n;} int len=0,data[20]; while(n){data[len++]=n%10;n/=10;} if(!len)data[len++]=0; while(len--)putchar(data[len]+'0');}void Init(){ for(int i=2;i<=1000;i++) { g[i].clear();int temp=i; for(int j=1;j<=11;j++) if(temp%prime[j]==0) { while(temp%prime[j]==0)temp/=prime[j]; g[i].push_back(prime[j]); } if(temp!=1)g[i].push_back(temp); }}int solve(int a,int m){ int sz=g[a].size(); int ret=0; if(sz==1) ret=m-m/g[a][0]; else if(sz==2) ret=m-m/g[a][0]-m/g[a][1]+m/(g[a][0]*g[a][1]); else if(sz==3){ int a1=g[a][0],a2=g[a][1],a3=g[a][2]; ret=m-m/a1-m/a2-m/a3+m/(a1*a2)+m/(a1*a3)+m/(a2*a3)-m/(a1*a2*a3); } else if(sz==4){ int a1=g[a][0],a2=g[a][1],a3=g[a][2],a4=g[a][3]; ret=m-m/a1-m/a2-m/a3-m/a4+m/(a1*a2)+m/(a1*a3)+m/(a1*a4)+m/(a2*a3)+m/(a2*a4)+m/(a3*a4)-m/(a1*a2*a3)-m/(a1*a2*a4)-m/(a1*a3*a4)-m/(a2*a3*a4)+m/(a1*a2*a3*a4); } else if(sz==5){ int a1=g[a][0], a2=g[a][1], a3=g[a][2], a4=g[a][3], a5=g[a][4]; ret=m-m/a1-m/a2-m/a3-m/a4-m/a5+m/(a1*a2)+m/(a1*a3)+m/(a1*a4)+m/(a1*a5)+m/(a2*a3)+m/(a2*a4)+m/(a2*a5)+m/(a3*a4)+m/(a3*a5)+m/(a4*a5)-m/(a1*a2*a3)-m/(a1*a2*a4)-m/(a1*a2*a5)-m/(a1*a3*a4)-m/(a1*a3*a5)-m/(a1*a4*a5)-m/(a2*a3*a4)-m/(a2*a3*a5)-m/(a2*a4*a5)-m/(a3*a4*a5)+m/(a1*a2*a3*a4)+m/(a1*a2*a3*a5)+m/(a1*a2*a4*a5)+m/(a1*a3*a4*a5)+m/(a2*a3*a4*a5)-m/(a1*a2*a3*a4*a5); } return ret-1;}int Gcd(int a,int b){ if(b==0)return a; return Gcd(b,a%b);}void build(int l,int r,int Ind){ if(l==r){gcd[Ind]=a[l];return;} int mid=(l+r)>>1; build(l,mid,Ind<<1); build(mid+1,r,(Ind<<1)+1); gcd[Ind]=Gcd(gcd[Ind<<1],gcd[(Ind<<1)+1]);}void Modify(int a,int l,int r,int Ind,int d){ //printf("Up l=%d r=%d\n",l,r); if(l==r&&l==a){gcd[Ind]=d;return;} int mid=(l+r)>>1; if(a<=mid)Modify(a,l,mid,Ind<<1,d); else Modify(a,mid+1,r,(Ind<<1)+1,d); gcd[Ind]=Gcd(gcd[Ind<<1],gcd[(Ind<<1)+1]); //printf("Down l=%d r=%d gcd[%d]=%d\n",l,r,Ind,gcd[Ind]);}void query(int a,int b,int l,int r,int Ind){ //printf("Up a=%d b=%d l=%d r=%d ",a,b,l,r);printf("result=%d\n",result); if(a<=l&&r<=b){result=Gcd(result,gcd[Ind]);return;} int mid=(l+r)>>1; if(a<=mid)query(a,b,l,mid,Ind<<1); if(mid<b)query(a,b,mid+1,r,(Ind<<1)+1); gcd[Ind]=Gcd(gcd[Ind<<1],gcd[(Ind<<1)+1]); //printf("Down a=%d b=%d l=%d r=%d gcd[%d]=%d\n",a,b,l,r,Ind,gcd[Ind]);printf("result=%d\n",result);}void Cal(){ ans[1]=-1; for(int i=2;i<=1000;i++) { int cnt=0,k=m/i,r=m%i; for(int j=1;j<i;j++)if(Gcd(i,j)==1)cnt++; ans[i]=cnt*k-1; for(int j=1;j<=r;j++)if(Gcd(i,j)==1)ans[i]++; } /*ans[1]=-1; for(int i=2;i<=1000;i++)//可能出现的gcd值 { int cnt=0,pr=m/i,la=m%i; for(int j=1;j<i;j++)if(Gcd(i,j)==1)cnt++; ans[i]=cnt*pr-1; for(int j=1;j<=la;j++)if(Gcd(i,j)==1)ans[i]++; }*/}int main(){ #ifdef LOCAL freopen("input.txt","r",stdin); #endif // LOCALf while(read(n)) { read(m);read(q); int kind,l,r,x,v; for(int i=1;i<=n;i++)read(a[i]); build(1,n,1); Init(); for(int i=1;i<=q;i++) { read(kind); if(kind==1) { read(l);read(r); result=a[r];query(l,r,1,n,1); if(result==1){write(-1);printf("\n");} else { int ret=solve(result,m); write(ret);printf("\n"); } } if(kind==2){read(x);read(v);a[x]=v;Modify(x,1,n,1,v);} } } return 0;}
0 0
- BUPT Summer Journey #test7 E
- BUPT Summer Journey #test7 A
- BUPT Summer Journey #test7 B
- BUPT Summer Journey #test7 C
- BUPT Summer Journey #test7 D
- BUPT Summer Journey #test1 E
- BUPT Summer Journey #test2 E
- BUPT Summer Journey #test3 E
- BUPT Summer Journey #test4 E
- BUPT Summer Journey #test5 E
- BUPT Summer Journey #test6 E
- BUPT Summer Journey #test8 E
- BUPT Summer Journey #test11 E
- BUPT Summer Journey #test1 A
- BUPT Summer Journey #test1 B
- BUPT Summer Journey #test1 C
- BUPT Summer Journey #test1 D
- BUPT Summer Journey #test2 A
- MySQL数据库插入中文出现“Incrrect Strng value '\xE9\x9C\x82'"错误
- 字典树 详解
- 去掉ExpandableListView的箭头图标
- Android设置RadioButton在文字的右边
- LoadRunner设置检查点的几种方法介绍
- BUPT Summer Journey #test7 E
- 64位Linux上编译32位软件
- 清除浮动的方法
- poj 1656 Counting Black
- mantle相关,待研究
- android setTag (int key, Object tag)抛出IllegalArgumentException的问题
- 习近平名字在党媒出现次数稍逊毛泽东
- hdu 1079 Calendar Game 博弈(组合游戏) sg函数
- MRTG—网络监控工具