zoukankan      html  css  js  c++  java
  • HDU 5634 (线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634

    题意:给出 n 个数,有三种操作,把区间的 ai 变为 φ(ai);把区间的 ai 变为 x;查询区间和。

    题解:因为一个数由 ai 变为 φ(ai)在 log 次之后会变为 1 并且一直都为 1,考虑在没有第二种操作的情况下,只需要暴力修改记录区间最大值是否大于 1 即可。在加入第二个操作之后,可以发现对区间进行修改的话,一个区间内的数都是相同的,进行第一个操作可以对整个区间进行操作,故可以用线段树多记录一个区间内的数是否相同即可。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define ll long long
      4 #define ull unsigned long long
      5 #define mst(a,b) memset((a),(b),sizeof(a))
      6 #define mp(a,b) make_pair(a,b)
      7 #define pi acos(-1)
      8 #define pii pair<int,int>
      9 #define pb push_back
     10 const int INF = 0x3f3f3f3f;
     11 const double eps = 1e-6;
     12 const int MAXN = 3e5 + 10;
     13 const int MAXM = 1e7 + 10;
     14 const ll mod = 1e9 + 7;
     15 
     16 bool check[MAXM];
     17 int phi[MAXM], prime[MAXM / 10], tot;
     18 
     19 void init(int N) {
     20     tot = 0;
     21     phi[1] = 1;
     22     for(int i = 2; i <= N; i++) {
     23         if(!check[i]) {
     24             prime[tot++] = i;
     25             phi[i] = i - 1;
     26         }
     27         for(int j = 0; j < tot; j++) {
     28             if(i * prime[j] > N) break;
     29             check[i * prime[j]] = true;
     30             if(i % prime[j] == 0) {
     31                 phi[i * prime[j]] = phi[i] * prime[j];
     32                 break;
     33             } else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
     34         }
     35     }
     36 }
     37 
     38 int a[MAXN],num[MAXN<<2];
     39 ll sum[MAXN<<2];
     40 
     41 void pushup(int rt) {
     42     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     43     if(num[rt<<1] == num[rt<<1|1]) num[rt] = num[rt<<1];
     44     else num[rt] = 0;
     45 //    num[rt] = (num[rt<<1] == num[rt<<1|1]) ? num[rt] : 0;
     46 }
     47 
     48 void build(int rt,int l,int r) {
     49     if(l == r) {
     50         sum[rt] = num[rt] = a[l];
     51         return ;
     52     }
     53     int mid = (l + r) >> 1;
     54     build(rt<<1,l,mid);
     55     build(rt<<1|1,mid + 1,r);
     56     pushup(rt);
     57 }
     58 
     59 void pushdown(int rt,int l,int r) {
     60     if(num[rt]) {
     61         int mid = (l + r) >> 1;
     62         num[rt<<1] = num[rt<<1|1] = num[rt];
     63         sum[rt<<1] = 1ll * num[rt<<1] * (mid - l + 1);
     64         sum[rt<<1|1] = 1ll * num[rt<<1|1] * (r - mid);
     65         num[rt] = 0;
     66     }
     67 }
     68 
     69 void update1(int rt,int l,int r,int ql,int qr) {
     70     if(ql > qr) return ;
     71     if(num[rt] && l == ql && r == qr) {
     72         num[rt] = phi[num[rt]];
     73         sum[rt] = 1ll * num[rt] * (r - l + 1);
     74         return ;
     75     }
     76     pushdown(rt,l,r);
     77     int mid = (l + r) >> 1;
     78     if(qr <= mid) update1(rt<<1,l,mid,ql,qr);
     79     else if(ql > mid) update1(rt<<1|1,mid + 1,r,ql,qr);
     80     else {
     81         update1(rt<<1,l,mid,ql,mid);
     82         update1(rt<<1|1,mid + 1,r,mid + 1,qr);
     83     }
     84     pushup(rt);
     85 }
     86 
     87 void update2(int rt,int l,int r,int ql,int qr,int val) {
     88     if(ql > qr) return ;
     89     if(l == ql && r == qr) {
     90         num[rt] = val;
     91         sum[rt] = 1ll * num[rt] * (r - l + 1);
     92         return ;
     93     }
     94     pushdown(rt,l,r);
     95     int mid = (l + r) >> 1;
     96     if(qr <= mid) update2(rt<<1,l,mid,ql,qr,val);
     97     else if(ql > mid) update2(rt<<1|1,mid + 1,r,ql,qr,val);
     98     else {
     99         update2(rt<<1,l,mid,ql,mid,val);
    100         update2(rt<<1|1,mid + 1,r,mid + 1,qr,val);
    101     }
    102     pushup(rt);
    103 }
    104 
    105 ll query(int rt,int l,int r,int ql,int qr) {
    106     if(ql == l && qr == r) return sum[rt];
    107     pushdown(rt,l,r);
    108     int mid = (l + r) >> 1;
    109     if(qr <= mid) return query(rt<<1,l,mid,ql,qr);
    110     else if(ql > mid) return query(rt<<1|1,mid + 1,r,ql,qr);
    111     else return query(rt<<1,l,mid,ql,mid) + query(rt<<1|1,mid + 1,r,mid + 1,qr);
    112 }
    113 
    114 int main() {
    115 #ifdef local
    116     freopen("data.txt", "r", stdin);
    117 //    freopen("data.txt", "w", stdout);
    118 #endif
    119     init(1e7);
    120     int t;
    121     scanf("%d",&t);
    122     while(t--) {
    123         int n,m;
    124         scanf("%d%d",&n,&m);
    125         for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
    126         build(1,1,n);
    127         while(m--) {
    128             int op,l,r,x;
    129             scanf("%d",&op);
    130             if(op == 1) {
    131                 scanf("%d%d",&l,&r);
    132                 update1(1,1,n,l,r);
    133             } else if(op == 2) {
    134                 scanf("%d%d%d",&l,&r,&x);
    135                 update2(1,1,n,l,r,x);
    136             } else if(op == 3) {
    137                 scanf("%d%d",&l,&r);
    138                 printf("%lld
    ",query(1,1,n,l,r));
    139             }
    140         }
    141     }
    142     return 0;
    143 }
  • 相关阅读:
    iOS项目中常见的文件
    RN 导入原有Xcode项目中,引入Pod依赖出现的问题与解决
    Xcode中StoryBoard Reference 新特性的使用
    非等高cell实战(01)-- 实现微博页面
    iOS回顾笔记(09) -- Cell的添加、删除、更新、批量操作
    iOS回顾笔记(08) -- 自定义Cell的类型和创建步骤总结
    unittest中的测试固件
    unittest测试用例的执行顺序
    unittest各个组件之间的关系
    ubuntu16.04开机时的.local问题
  • 原文地址:https://www.cnblogs.com/scaulok/p/9873528.html
Copyright © 2011-2022 走看看