HDU 5831(思路题目)

来源:互联网 发布:java初级工程师简历 编辑:程序博客网 时间:2024/06/06 15:47

本题目的意思是给定一个长为n的数组:

     给定很多查询区间 li,ri;


首先来观察一下,对于两个区间直接存储待查询的信息,那么是否可以通过维护一些值直接推导出合并区间的待查询值 ? 答案是可以,因为合并时只需左右子区间维护关于包含左右端点往左右延伸的gcd数目,gcd数组,和个数数组,即可合并。有了合并,就迎刃而解。 通过这题,想用线段树时,多关注一下有没有上推的性质。

#include <iostream>#include <string.h>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;#define rep1(i,x,y) for(int i=x;i<=(int)y;i++)#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ls rt<<1#define rs rt<<1|1const int N = 10100;typedef long long ll;int gcd(int a,int b){return (b==0 ? a:gcd(b,a%b));}struct node{   int lsum[35],lcnt,lgcd[35];   int rsum[35],rcnt,rgcd[35];   ll val;   void push_up(node a,node b){      val = a.val+b.val;      rep1(i,1,a.rcnt) rep1(j,1,b.lcnt){           int g = gcd(a.rgcd[i],b.lgcd[j]);           val+=(ll)g*a.rsum[i]*b.lsum[j];      }      lcnt = a.lcnt;      rep1(i,1,a.lcnt) lsum[i]=a.lsum[i],lgcd[i]=a.lgcd[i];      for(int i=1;i<=b.lcnt;){          while(i<=b.lcnt && gcd(lgcd[lcnt],b.lgcd[i])==lgcd[lcnt]) {               lsum[lcnt]+=b.lsum[i++];          }          if(i <= b.lcnt){              ++lcnt; lsum[lcnt]=b.lsum[i]; lgcd[lcnt]=gcd(lgcd[lcnt-1],b.lgcd[i]);              ++i;          }      }      rcnt = b.rcnt;      rep1(i,1,b.rcnt) rsum[i]=b.rsum[i],rgcd[i]=b.rgcd[i];      for(int i=1;i<=a.rcnt;){          while(i<=a.rcnt && gcd(rgcd[rcnt],a.rgcd[i])==rgcd[rcnt]) {               rsum[rcnt]+=a.rsum[i++];          }          if(i <= a.rcnt){              ++rcnt; rsum[rcnt]=a.rsum[i]; rgcd[rcnt]=gcd(rgcd[rcnt-1],a.rgcd[i]);              ++i;          }      }   }}a[N<<2];int ori[N];void build(int l,int r,int rt){   if(l == r){      a[rt].lcnt=a[rt].rcnt=1; a[rt].val=a[rt].lgcd[1]=a[rt].rgcd[1]=ori[l];      a[rt].lsum[1]=a[rt].rsum[1]=1;      return ;   }   int m=(l+r)>>1;   build(lson);   build(rson);   a[rt].push_up(a[ls],a[rs]);}node query(int l,int r,int rt,int L,int R){   if(L<=l && r<=R) {      return a[rt];   }   int m=(l+r)>>1;   if(R<=m) return query(lson,L,R);   else if(L>m) return query(rson,L,R);   else{      node res;      res.push_up(query(lson,L,R),query(rson,L,R));      return res;   }}int n;int main(){    int T;    scanf("%d",&T);    while(T--){      scanf("%d",&n);      rep1(i,1,n) scanf("%d",&ori[i]);      build(1,n,1);      int Q;      scanf("%d",&Q);      while(Q--){         int l,r;         scanf("%d %d",&l,&r);         printf("%I64d\n",query(1,n,1,l,r).val);      }    }    return 0;}


Internet


本题目

#include <iostream>#include <string.h>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;#define rep1(i,x,y) for(int i=x;i<=(int)y;i++)#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ls rt<<1#define rs rt<<1|1const int N = 10100;typedef long long ll;int gcd(int a,int b){return (b==0 ? a:gcd(b,a%b));}struct node{   int lsum[35],lcnt,lgcd[35];   int rsum[35],rcnt,rgcd[35];   ll val;   void push_up(node a,node b){      val = a.val+b.val;      rep1(i,1,a.rcnt) rep1(j,1,b.lcnt){           int g = gcd(a.rgcd[i],b.lgcd[j]);           val+=(ll)g*a.rsum[i]*b.lsum[j];      }      lcnt = a.lcnt;      rep1(i,1,a.lcnt) lsum[i]=a.lsum[i],lgcd[i]=a.lgcd[i];      for(int i=1;i<=b.lcnt;){          while(i<=b.lcnt && gcd(lgcd[lcnt],b.lgcd[i])==lgcd[lcnt]) {               lsum[lcnt]+=b.lsum[i++];          }          if(i <= b.lcnt){              ++lcnt; lsum[lcnt]=b.lsum[i]; lgcd[lcnt]=gcd(lgcd[lcnt-1],b.lgcd[i]);              ++i;          }      }      rcnt = b.rcnt;      rep1(i,1,b.rcnt) rsum[i]=b.rsum[i],rgcd[i]=b.rgcd[i];      for(int i=1;i<=a.rcnt;){          while(i<=a.rcnt && gcd(rgcd[rcnt],a.rgcd[i])==rgcd[rcnt]) {               rsum[rcnt]+=a.rsum[i++];          }          if(i <= a.rcnt){              ++rcnt; rsum[rcnt]=a.rsum[i]; rgcd[rcnt]=gcd(rgcd[rcnt-1],a.rgcd[i]);              ++i;          }      }   }}a[N<<2];int ori[N];void build(int l,int r,int rt){   if(l == r){      a[rt].lcnt=a[rt].rcnt=1; a[rt].val=a[rt].lgcd[1]=a[rt].rgcd[1]=ori[l];      a[rt].lsum[1]=a[rt].rsum[1]=1;      return ;   }   int m=(l+r)>>1;   build(lson);   build(rson);   a[rt].push_up(a[ls],a[rs]);}node query(int l,int r,int rt,int L,int R){   if(L<=l && r<=R) {      return a[rt];   }   int m=(l+r)>>1;   if(R<=m) return query(lson,L,R);   else if(L>m) return query(rson,L,R);   else{      node res;      res.push_up(query(lson,L,R),query(rson,L,R));      return res;   }}int n;int main(){    int T;    scanf("%d",&T);    while(T--){      scanf("%d",&n);      rep1(i,1,n) scanf("%d",&ori[i]);      build(1,n,1);      int Q;      scanf("%d",&Q);      while(Q--){         int l,r;         scanf("%d %d",&l,&r);         printf("%I64d\n",query(1,n,1,l,r).val);      }    }    return 0;}


  

0 0
原创粉丝点击