zoukankan      html  css  js  c++  java
  • codeforces 914 D Bash and a Tough Math Puzzle

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cstdio>
     6 using namespace std;
     7 const int N=500100;
     8 int n,a[N],m;
     9 struct tree{
    10     int l,r,gcd;
    11 }tr[N*5];
    12 int gcd(int x,int y){
    13     if(y==0)return x;
    14     else return gcd(y,x%y);
    15 }
    16 void build(int l,int r,int now){
    17     tr[now].l=l;tr[now].r=r;
    18     if(l==r){
    19         tr[now].gcd=a[l];
    20         return;
    21     }
    22     int mid=(l+r)>>1;
    23     build(l,mid,now*2);
    24     build(mid+1,r,now*2+1);
    25     tr[now].gcd=gcd(tr[now*2].gcd,tr[now*2+1].gcd);
    26 }
    27 void change(int x,int y,int now){
    28 //    cout<<tr[now].l<<" "<<tr[now].r<<" "<<x<<endl;
    29     if(tr[now].l==x&&tr[now].r==x){
    30         tr[now].gcd=y;
    31         return ;
    32     }
    33     int mid=(tr[now].l+tr[now].r)>>1;
    34     if(x>mid)change(x,y,now*2+1);
    35     else change(x,y,now*2);
    36     tr[now].gcd=gcd(tr[now*2].gcd,tr[now*2+1].gcd);
    37 }
    38 int check(int l,int r,int x,int now){
    39     if(tr[now].gcd%x==0)return 0;
    40     if(tr[now].l==l&&tr[now].r==r){
    41         if(l==r)return 1;
    42         if(tr[now*2].gcd%x==0)return check(tr[now*2+1].l,tr[now*2+1].r,x,now*2+1);
    43         if(tr[now*2+1].gcd%x==0)return check(tr[now*2].l,tr[now*2].r,x,now*2);
    44         return 2;
    45     }
    46     int mid=(tr[now].l+tr[now].r)>>1;
    47     if(l>mid)return check(l,r,x,now*2+1);
    48     else if(r<=mid)return check(l,r,x,now*2);
    49     else{
    50         return check(l,mid,x,now*2)+check(mid+1,r,x,now*2+1);
    51     } 
    52 }
    53 int main(){
    54     scanf("%d",&n);
    55     for(int i=1;i<=n;i++){
    56         scanf("%d",&a[i]);
    57     }
    58     build(1,n,1);
    59     scanf("%d",&m);
    60     for(int i=1;i<=m;i++){
    61         int k;
    62         scanf("%d",&k);
    63         if(k==1){
    64             int l,r,x;
    65             scanf("%d%d%d",&l,&r,&x);
    66             if(check(l,r,x,1)<=1)printf("YES
    ");
    67             else printf("NO
    ");
    68         }
    69         else{
    70             int x,y;
    71             scanf("%d%d",&x,&y);
    72             change(x,y,1);
    73         }
    74     }
    75     return 0;
    76 }
    View Code

    题意

    •给出一段序列(1≤n≤5*105),两个操作(1≤q≤4*105)

    •操作1 给出l,r,x

    •求区间l-r的gcd,如果至多能改掉区间内的一个数,使gcd是x的倍数,那么输出YES,否则输出NO

    •操作2 给出pos,x

    •将序列中pos位置上的数字改为x

    题解

    线段树,维护区间的gcd

    因为题目询问删除一个数,我们把整个区间分成两块,如果两边的gcd都是x的倍数显然是可以的,如果都不是gcd的倍数,就不行了,因为使两个gcd的gcd为x的倍数,这两个gcd应该都至少含有x因子。如果一个gcd是x的倍数,一个不是,那就递归处理不是的那个区间。

  • 相关阅读:
    检索 COM 类工厂中 CLSID 为 {0002450000000000C000000000000046} 的组件时失败,原因是出现以下错误: 80070005。
    行列转换(sqlserver2005 的新方法)
    今天开始要详细的记录学习sharepoint 的进度和相关的一些资料
    SQL SERVER 2005 数据库状态为“可疑”的解决方法
    弹出窗口window.open()的参数列表
    C#术语&&C#关键字
    把一个 ASP.NET 程序转换为了 Web Services
    修饰符(C# 参考)
    C# 中的常用正则表达式
    1、String.format()与String.valueOf()区别 && 2、string.split()
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9306754.html
Copyright © 2011-2022 走看看