zoukankan      html  css  js  c++  java
  • SPOJ DCEPC11I

    题目大意:

    就是给定一段区间令其中的数增加一个递增序列(也就是说第一个+1,第二个+2.。。。。)

    询问操作是区间的和

    这里的查询很简单,但是对于添加递增序列入区间就比较搞脑子了

    我们需要一个add[]作为区间的首个数字增加的值,del[]表示等差数列的公差,因为你每次添加进入一个等差数列,是可以叠加的但公差变为了del[ls]+=del[o]

    这里主要是pushdown函数的写法

    我们要用到等差公式的求和:S =a*n+n(n-1)*d/2

    void push_down(int o,int x,int y)
    {
        int mid=(x+y)/2,ls=o<<1,rs=o<<1|1;
        if(add[o]||del[o]){
            int t1=mid-x+1,t2=y-mid;
            LL a2=add[o]+t1*del[o];
            sum[ls]+=add[o]*t1+t1*(t1-1)*del[o]/2;
            sum[rs]+=a2*t2+t2*(t2-1)*del[o]/2;
            add[ls]+=add[o],add[rs]+=a2;
            del[ls]+=del[o],del[rs]+=del[o];
            add[o]=del[o]=0;
        }
    }

    总代码如下所示:

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 #define L ls,x,mid
     5 #define R rs,mid+1,y
     6 #define LL long long
     7 #define N 100010
     8 LL sum[N<<2],add[N<<2];
     9 int del[N<<2];
    10 void push_up(int o)
    11 {
    12     sum[o]=sum[o<<1]+sum[o<<1|1];
    13 }
    14 void push_down(int o,int x,int y)
    15 {
    16     int mid=(x+y)/2,ls=o<<1,rs=o<<1|1;
    17     if(add[o]||del[o]){
    18         int t1=mid-x+1,t2=y-mid;
    19         LL a2=add[o]+t1*del[o];
    20         sum[ls]+=add[o]*t1+t1*(t1-1)*del[o]/2;
    21         sum[rs]+=a2*t2+t2*(t2-1)*del[o]/2;
    22         add[ls]+=add[o],add[rs]+=a2;
    23         del[ls]+=del[o],del[rs]+=del[o];
    24         add[o]=del[o]=0;
    25     }
    26 }
    27 void build(int o,int x,int y)
    28 {
    29     int mid=(x+y)/2,ls=o<<1,rs=o<<1|1;
    30     sum[o]=del[o]=add[o]=0;
    31     if(x==y) return;
    32     build(L);
    33     build(R);
    34 }
    35 void update(int o,int x,int y,int s,int t)
    36 {
    37     int mid=(x+y)/2,ls=o<<1,rs=o<<1|1;
    38     if(x>=s&&y<=t){
    39         add[o]+=x-s+1;
    40         sum[o]+=(x-s+1)*(y-x+1)+(y-x+1)*(y-x)/2;
    41         del[o]++;
    42         return;
    43     }
    44     push_down(o,x,y);
    45     if(mid>=s) update(L,s,t);
    46     if(mid<t) update(R,s,t);
    47     push_up(o);
    48 }
    49 void query(int o,int x,int y,int s,int t,LL &ans)
    50 {
    51     int mid=(x+y)/2,ls=o<<1,rs=o<<1|1;
    52     if(x>=s&&y<=t){
    53         ans+=sum[o];
    54         return;
    55     }
    56     push_down(o,x,y);
    57     if(mid>=s) query(L,s,t,ans);
    58     if(mid<t) query(R,s,t,ans);
    59 }
    60 int main()
    61 {
    62     int n,q,op,a,b;
    63     scanf("%d%d",&n,&q);
    64     build(1,1,n);
    65     for(int i=0;i<q;i++){
    66         scanf("%d%d%d",&op,&a,&b);
    67         if(op){
    68             LL ans=0;
    69             query(1,1,n,a,b,ans);
    70             printf("%lld
    ",ans);
    71         }
    72         else update(1,1,n,a,b);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    网站安全编程 黑客入侵 脚本黑客 高级语法入侵 C/C++ C# PHP JSP 编程
    【算法导论】贪心算法,递归算法,动态规划算法总结
    cocoa2dx tiled map添加tile翻转功能
    8月30日上海ORACLE大会演讲PPT下载
    【算法导论】双调欧几里得旅行商问题
    Codeforces Round #501 (Div. 3) B. Obtaining the String (思维,字符串)
    Codeforces Round #498 (Div. 3) D. Two Strings Swaps (思维)
    Educational Codeforces Round 89 (Rated for Div. 2) B. Shuffle (数学,区间)
    洛谷 P1379 八数码难题 (BFS)
    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3901222.html
Copyright © 2011-2022 走看看