zoukankan      html  css  js  c++  java
  • HDU4267(2012年长春站)

    这道题真的是好题,让我对线段树有了全新的认识,至少让我真正感受到了线段树的神奇。

    题意是就是线段树区间更新,单点询问的问题,不过这个题好就好在它的区间更新的点并不连续!

    adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0.

    关键在于更新的点所满足的条件  1.在区间[a,b]中。 2.关于k的余数与(a%k)相等。

    其中第二个条件保证了更新的点不连续(但如果传统的先判断再更新,则线段树失去了优势,因为始终会超时)。

    本题突破口在于K的大小(1 <= k <= 10),结合第二个条件,我们可以想到在线段树的 Lazy标记上做文章。

    当k==1 余数有 0

    当k==2 余数有 0,1

    当k==3 余数有 0,1,2

    。。。。。

    可以看到,只有55种情况,那么我们只需要将线段树的 Lazy标记 扩充为大小55的数组,

    然后根据相应的余数情况进行更新与查询即可。

      1 #include<iostream>
      2 #include<sstream>
      3 #include<stack>
      4 #include<cstdio>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<climits>
      8 #include<cctype>
      9 #include<queue>
     10 #include<algorithm>
     11 #include<cmath>
     12 #include<map>
     13 #include<set>
     14 #define lson root<<1,l,mid
     15 #define rson root<<1|1,mid+1,r
     16 
     17 #define inf 0x3f3f3f3f
     18 #define N 50010
     19 #define maxn 10001000
     20 #define mod 1000000007
     21 using namespace std;
     22 
     23 int a[N];
     24 int b[11][11];     //用于将55种余数情况一 一 对 应
     25 struct NODE{
     26     int l,r;
     27     int v;
     28     int b[55];
     29     int mid(){
     30         return (l+r)>>1;
     31     }
     32 }node[N<<2];
     33 
     34 void build(int root,int l,int r)
     35 {
     36     node[root].l=l;
     37     node[root].r=r;
     38     node[root].v=0;
     39     memset(node[root].b,0,sizeof(node[root].b));
     40     if(l==r) return;
     41     int mid=node[root].mid();
     42     build(lson);
     43     build(rson);
     44 }
     45 
     46 void pushdown(int root)   //关于pushdown函数,个人觉得只需要询问时调用就行了,而且也过了,应该没问题,有的话请指出,谢谢
     47 {
     48     for(int i=1; i<=10; ++i)
     49     {
     50         for(int j=0; j<i; ++j)
     51         {
     52             node[root<<1].b[b[i][j]]+=node[root].b[b[i][j]];
     53             node[root<<1|1].b[b[i][j]]+=node[root].b[b[i][j]];
     54         }
     55     }
     56     memset(node[root].b,0,sizeof(node[root].b));
     57 }
     58 
     59 void update(int x,int y,int root,int v,int k,int rd)
     60 {
     61     if(node[root].l==x&&node[root].r==y)
     62     {
     63         node[root].b[b[k][rd]]+=v;
     64         node[root].v+=v;
     65         return;
     66     }
     67     int mid=node[root].mid();
     68     if(y<=mid) update(x,y,root<<1,v,k,rd);
     69     else if(x>mid) update(x,y,root<<1|1,v,k,rd);
     70     else
     71     {
     72         update(x,mid,root<<1,v,k,rd);
     73         update(mid+1,y,root<<1|1,v,k,rd);
     74     }
     75 }
     76 
     77 int query(int root,int x)
     78 {
     79     if(node[root].l==x&&node[root].r==x)
     80     {
     81         int ans=0;
     82         for(int i=1; i<=10; ++i)
     83             ans+=node[root].b[b[i][x%i]];
     84         return ans;
     85     }
     86     pushdown(root);
     87     int mid=node[root].mid();
     88     if(x<=mid) return query(root<<1,x);
     89     else return query(root<<1|1,x);
     90 }
     91 
     92 int main()
     93 {
     94    // freopen("lxx.txt","r",stdin);
     95     int group,figure,i,j,x,y,k,v,num;
     96     int cnt=0;
     97     for(i=1; i<=11; ++i)
     98         for(j=0; j<i; ++j)
     99             b[i][j]=cnt++;
    100     while(~scanf("%d",&group))
    101     {
    102         build(1,1,group);
    103         memset(a,0,sizeof(a));
    104         for(i=1; i<=group; ++i) scanf("%d",&a[i]);
    105         scanf("%d",&group);
    106         while(group--)
    107         {
    108             scanf("%d",&num);
    109             if(num==1)
    110             {
    111                 scanf("%d%d%d%d",&x,&y,&k,&v);
    112                 update(x,y,1,v,k,x%k);
    113             }
    114             else
    115             {
    116                 scanf("%d",&figure);
    117                 printf("%d
    ",query(1,figure)+a[figure]);
    118             }
    119         }
    120     }
    121     return 0;
    122 }

    不过感觉自己的代码风格还不够成熟,继续努力!

  • 相关阅读:
    标准C语言(9)
    标准C语言(8)
    标准C语言(7)
    标准C语言(6)
    标准C语言(5)
    标准C语言(4)
    标准C语言(3)
    标准C语言(1)
    Linux基础
    Kafka 学习笔记之 Kafka0.11之console-producer/console-consumer
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5222307.html
Copyright © 2011-2022 走看看