SCUT - 337 - 岩殿居蟹 - 线段树 - 树状数组
这个东西是个阶梯状的。那么可以考虑存两棵树,一棵树是阶梯的,另一棵树的平的,随便一减就是需要的阶梯。
优化之后貌似速度比树状数组还惊人。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read() {
    int x=0;
    int f=0;
    char c;
    do {
        c=getchar();
        if(c=='-')
            f=1;
    } while(c<'0'||c>'9');
    do {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    } while(c>='0'&&c<='9');
    return f?-x:x;
}
inline void _write(int x) {
    if(x>9)
        _write(x/10);
    putchar(x%10+'0');
}
inline void write(int x) {
    if(x<0) {
        putchar('-');
        x=-x;
    }
    _write(x);
    putchar('\n');
}
void TestCase(int ti);
int main() {
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
    //freopen("Yinku.out","w",stdout);
#endif // Yinku
    int T=1;
    for(int ti=1; ti<=T; ti++)
        TestCase(ti);
}
/*---  ---*/
const int MAXM=100000;
int a[MAXM+5];
int st[(MAXM<<2)+5];
int st2[(MAXM<<2)+5];
const int mod=1000000007;
inline int add(const int &a,const int &b){
    int res=a+b;
    return res>=mod?res-mod:res;
}
inline int sub(const int &a,const int &b){
    int res=a-b;
    return res<0?res+mod:res;
}
inline int mul(const int &a,const int &b){
    ll res=1ll*a*b;
    return res>=mod?res%mod:res;
}
inline void push_up(int o) {
    st[o]=add(st[o<<1],st[o<<1|1]);
    st2[o]=add(st2[o<<1],st2[o<<1|1]);
}
void build(int o,int l,int r) {
    if(l==r){
        st[o]=a[l];
        st2[o]=mul(l,a[l]);
    }
    else {
        int m=(l+r)>>1;
        build(o<<1,l,m);
        build(o<<1|1,m+1,r);
        push_up(o);
    }
}
void update(int o,int l,int r,int x,int v) {
    if(l==r) {
        st[o]=v;
        st2[o]=mul(x,v);
        return;
    } else {
        int m=(l+r)>>1;
        if(x<=m)
            update(o<<1,l,m,x,v);
        else if(x>=m+1)
            update(o<<1|1,m+1,r,x,v);
        push_up(o);
    }
}
int query1(int o,int l,int r,int a,int b) {
    if(a<=l&&r<=b) {
        return st[o];
    } else {
        int m=(l+r)>>1;
        int ans=0;
        if(a<=m)
            ans=query1(o<<1,l,m,a,b);
        if(b>=m+1)
            ans=add(ans,query1(o<<1|1,m+1,r,a,b));
        return ans;
    }
}
int query2(int o,int l,int r,int a,int b) {
    if(a<=l&&r<=b) {
        return st2[o];
    } else {
        int m=(l+r)>>1;
        int ans=0;
        if(a<=m)
            ans=query2(o<<1,l,m,a,b);
        if(b>=m+1)
            ans=add(ans,query2(o<<1|1,m+1,r,a,b));
        return ans;
    }
}
inline void TestCase(int ti) {
    int n,m;
    while(~scanf("%d",&n)) {
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        build(1,1,n);
        scanf("%d",&m);
        for(int i=1; i<=m; i++) {
            char a[2];
            int b,c;
            scanf("%s%d%d",a,&b,&c);
            if(a[0]=='Q') {
                printf("%d\n",sub(query2(1,1,n,b,c),mul(b-1,query1(1,1,n,b,c))));
            } else {
                update(1,1,n,b,c);
            }
        }
    }
}
这个树状数组就不太好懂了,不过空间是线段树的1/4,速度是其两倍。
单点改值就把差值update上去就可以了。然后记得把原始值也顺手改了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read() {
    int x=0;
    int f=0;
    char c;
    do {
        c=getchar();
        if(c=='-')
            f=1;
    } while(c<'0'||c>'9');
    do {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    } while(c>='0'&&c<='9');
    return f?-x:x;
}
inline void _write(int x) {
    if(x>9)
        _write(x/10);
    putchar(x%10+'0');
}
inline void write(int x) {
    if(x<0) {
        putchar('-');
        x=-x;
    }
    _write(x);
    putchar('\n');
}
void TestCase(int ti);
int main() {
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
    //freopen("Yinku.out","w",stdout);
#endif // Yinku
    int T=1;
    for(int ti=1; ti<=T; ti++)
        TestCase(ti);
}
/*---  ---*/
const int MAXM=100000;
int a[MAXM+5];
int bit[MAXM+5];
int bit2[MAXM+5];
int n;
const int mod=1000000007;
inline int add(const int &a,const int &b) {
    int res=a+b;
    return res>=mod?res-mod:res;
}
inline int sub(const int &a,const int &b) {
    int res=a-b;
    return res<0?res+mod:res;
}
inline int mul(const int &a,const int &b) {
    ll res=1ll*a*b;
    return res>=mod?res%mod:res;
}
inline int sum(int x,int bit[]) {
    int res=0;
    while(x) {
        res=add(res,bit[x]);
        x-=x&-x;
    }
    return res;
}
inline void update(int x,int v,int bit[]) {
    while(x<=n) {
        bit[x]=add(bit[x],v);
        x+=x&-x;
    }
}
inline int range_sum(int x,int y,int bit[]) {
    return sub(sum(y,bit),sum(x-1,bit));
}
inline void TestCase(int ti) {
    int m;
    while(~scanf("%d",&n)) {
        memset(bit,0,sizeof(bit));
        memset(bit2,0,sizeof(bit2));
        for(int i=1; i<=n; i++) {
            scanf("%d",&a[i]);
            update(i,a[i],bit);
            update(i,mul(i,a[i]),bit2);
        }
        scanf("%d",&m);
        for(int i=1; i<=m; i++) {
            char s[2];
            int b,c;
            scanf("%s%d%d",s,&b,&c);
            if(s[0]=='Q') {
                printf("%d\n",sub(range_sum(b,c,bit2),mul(b-1,range_sum(b,c,bit))));
            } else {
                int delta=sub(c,a[b]);
                update(b,delta,bit);
                update(b,mul(b,delta),bit2);
                a[b]=c;
            }
        }
    }
}
SCUT - 337 - 岩殿居蟹 - 线段树 - 树状数组的更多相关文章
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
		The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ... 
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
		Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ... 
- HDU 1556  线段树或树状数组,插段求点
		1.HDU 1556 Color the ball 区间更新,单点查询 2.题意:n个气球,每次给(a,b)区间的气球涂一次色,问最后每个气球各涂了几次. (1)树状数组 总结:树状数组是一个查 ... 
- HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树
		HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ... 
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
		谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ... 
- HDU 1394 Minimum Inversion Number(最小逆序数/暴力  线段树  树状数组  归并排序)
		题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS Memory Limit: 32768 K Description The inve ... 
- POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树
		题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ... 
- Turing Tree_线段树&树状数组
		Problem Description After inventing Turing Tree, 3xian always felt boring when solving problems abou ... 
- HDU 1166 敌兵布阵 (数状数组,或线段树)
		题意:... 析:可以直接用数状数组进行模拟,也可以用线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&quo ... 
随机推荐
- SQL2005 2008配置错误,无法识别的配置节 system.serviceModel  machine.config配置文件有问题
			当装上2008的时候,你以前的程序突然报出你的machine.config配置文件有问题,比如 “/” 应用程序中的服务器错误. 配置错误 说明 : 在处理向该请求提供服务所需的配置文件时出错.请检查 ... 
- Delphi TcxComboBox控件说明
			属性: Text:ComboBox 的文本信息 EditText: 也是给ComboBox 的文本信息赋值,但不同的是 给Text赋值会 触发 Change事件,也会触发 EditvaluesChan ... 
- MVC中ajax调用Controller的方法
			1. ajax代码: $.ajax({ async: false, cache: false, type: 'POST', contentType: "application/json&qu ... 
- Uva 10820 Send a Table(欧拉函数)
			对每个n,答案就是(phi[2]+phi[3]+...+phi[n])*2+1,简单的欧拉函数应用. #include<iostream> #include<cstdio> # ... 
- Struts2 - 配置文件详解
			<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ... 
- C++中Segmentation fault(Core Dump)错误处理
			什么是Core Dump? Core的意思是内存, Dump的意思是扔出来, 堆出来. 开发和使用Unix程序时, 有时程序莫名其妙的down了, 却没有任何的提示(有时候会提示core dumped ... 
- 【LeetCode】019. Remove Nth Node From End of List
			Given a linked list, remove the nth node from the end of list and return its head. For example, Give ... 
- 【LeetCode】015 3Sum
			题目: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find al ... 
- 【转】mysql查询当天所有数据sql语句
			mysql查询当天的所有信息: select * from test where year(regdate)=year(now()) and month(regdate)=month(now()) a ... 
- lvs-nat搭建httpd
			拓扑图: #172.16.252.10 [root@~ localhost]#route -n Kernel IP routing table Destination Gateway Genmask ... 
