• HDU 5828(线段树)


    Problem Rikka with Sequence

    题目大意

      维护一个序列,支持三种操作。

      操作1:区间加。  操作二:区间开根号(向下取整)。  操作3:区间求和。

    解题分析

      可以发现经过若干次操作后,整些区间内的数会趋向于相同。

      可以再开一个标记,表示这个区间内的数是否相同,这样可以优化一下区间开根号的复杂度。

      然后就卡过去了~~

      Pushdown的时候要注意不要把一个lazy标记往下传两次。

    参考程序

      1 #include <cstdio>
      2 #include <cmath>
      3 
      4 #define maxn 200008
      5 #define lson l , m , rt << 1
      6 #define rson m+1 , r , rt << 1 | 1
      7 #define eps 1e-8
      8 long long sum[maxn << 2],lazy[maxn << 2];
      9 long long tag[maxn << 2];
     10 int n;
     11 
     12 void Pushup(int rt){
     13     sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
     14     if (tag[rt << 1] == tag[rt << 1 | 1]) tag[rt]=tag[rt << 1]; else tag[rt] = 0;
     15 }
     16 
     17 void Pushdown(int rt,int m){
     18     if (tag[rt]){
     19         tag[rt << 1] = tag[rt];
     20         tag[rt << 1 | 1] = tag[rt];
     21         sum[rt << 1] = tag[rt] * (m-m/2);
     22         sum[rt << 1 | 1] = tag[rt] * (m/2);
     23         lazy[rt]=0;
     24     }
     25     if (lazy[rt]) {
     26         lazy[rt << 1] += lazy[rt];
     27         lazy[rt << 1 | 1] += lazy[rt];
     28         sum[rt << 1] += lazy[rt] * (m - m / 2);
     29         sum[rt << 1 | 1] += lazy[rt] * (m / 2);
     30         if (tag[rt << 1]) tag[rt << 1] += lazy[rt];
     31         if (tag[rt << 1 | 1]) tag[rt << 1 | 1] += lazy[rt];
     32         lazy[rt] = 0;
     33     }
     34 }
     35 
     36 void Build(int l,int r,int rt){
     37     lazy[rt] = 0;
     38     tag[rt] = 0;
     39     if (l==r) {
     40         scanf("%d",&sum[rt]);
     41         tag[rt]=sum[rt]; 
     42         return;
     43     }
     44     int m = (l + r) >> 1;
     45     Build(lson);
     46     Build(rson);
     47     Pushup(rt);
     48 }
     49 
     50 void Update(int L,int R,int val,int l,int r,int rt){
     51     if (L <= l && r <= R) {
     52         sum[rt] += 1ll*(r - l + 1) * val;
     53         lazy[rt] += val;
     54         if (tag[rt]) tag[rt]+=val;
     55         return;
     56     }
     57     Pushdown(rt,r - l + 1);
     58     int m = (l + r) >> 1;
     59     if (L <= m) Update(L,R,val,lson);
     60     if (m <  R) Update(L,R,val,rson);
     61     Pushup(rt);
     62 }
     63 
     64 void Update_2(int L,int R,int l,int r,int rt){
     65     if (L<=l && r<=R && tag[rt]){
     66         tag[rt] = (long long)(sqrt(tag[rt])+eps);
     67         sum[rt] = 1ll*tag[rt] * (r - l + 1);
     68         return;
     69     }
     70     Pushdown(rt,r - l + 1);
     71     int m = (l + r) >> 1;
     72     if (L <= m) Update_2(L,R,lson);
     73     if (m <  R) Update_2(L,R,rson);
     74     Pushup(rt);
     75 }
     76 
     77 long long Query(int L,int R,int l,int r,int rt){
     78     if (L <= l && r <= R) {
     79         return sum[rt];
     80     }
     81     Pushdown(rt,r - l + 1);
     82     int m = (l + r) >> 1;
     83     long long res = 0;
     84     if (L <= m) res += Query(L,R,lson);
     85     if (m <  R) res += Query(L,R,rson);
     86     return res;
     87 }
     88 
     89 
     90 int main() {
     91     int T;
     92     scanf("%d",&T);
     93     while (T--){
     94         int Q;
     95         scanf("%d %d",&n,&Q);
     96         Build(1,n,1);
     97         while (Q--) {
     98             int x,y,z,w;
     99             scanf("%d",&w);
    100             if (w==1) {
    101                 scanf("%d%d%d",&x,&y,&z);
    102                 Update(x,y,z,1,n,1);
    103             }
    104             if (w==2){
    105                 scanf("%d%d",&x,&y);
    106                 Update_2(x,y,1,n,1);
    107             }
    108             if (w==3){
    109                 scanf("%d%d",&x,&y);
    110                 printf("%I64d
    ",Query(x,y,1,n,1));                
    111             }
    112         }
    113     }
    114 }
    View Code
  • 相关阅读:
    排列算法问题
    g00 网站说明
    leetcode 401. Binary Watch
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月7日)
    北京Uber优步司机奖励政策(1月6日)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月6日)
    北京Uber优步司机奖励政策(1月5日)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月5日)
    全国Uber优步司机奖励政策 (12月28日-1月3日)
    全国Uber优步司机奖励政策 (1月4日-1月10日)
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5762254.html
Copyright © 2020-2023  润新知