线段树

http://blog.csdn.net/liuledidai/article/details/9964697

( 1 )线段树功能: 单点替换 区间最值
I Hate It

#include <cstdio>
#include <algorithm>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 222222;
int MAX[maxn<<2];
void PushUP(int rt) {
MAX[rt] = max(MAX[rt<<1] , MAX[rt<<1|1]);
}
void build(int l,int r,int rt) {  //rt当前节点编号
    if (l == r)//l==r,说明rt节点是叶子节点
    {           //由于先build左子树,再build右子树,所以最终会先写完左边的叶子节点,再写完右边的叶子节点
        scanf("%d",&MAX[rt]);
        return ;
    }
    int m = (l + r) >> 1;
    build(l , m , rt << 1);//rt*2
    build(m + 1 , r , rt << 1 | 1);//rt*2+1( rt*2 是偶数,rt<<1|1=rt*2+1)
    PushUP(rt);
}
void update(int p,int sc,int l,int r,int rt)
{
    if (l == r) {
        MAX[rt] = sc;
        return ;
    }
    int m = (l + r) >> 1;
    if (p <= m) update(p , sc , l , m , rt << 1);
    else update(p , sc , m + 1 , r , rt << 1 | 1);
    //PushUP(rt);
     MAX[rt] = max(MAX[rt<<1] , MAX[rt<<1|1]);
}
int query(int L,int R,int l,int r,int rt)//l r为线段树的完美区间,l mid为左子树区间, mid+1,r为右子树区间
{                                        //L , R是当前查询区间,它可能不是完美的,有可能包含左子树区间的一部分或者右子树的一部分
    if(L<=l&&R>=r) return MAX[rt];
    int m = (l + r) >> 1;
    int ret = 0;
    if(m>=R) return query(L,R,l,m,rt<<1);
    else if(m+1<=L) return query(L,R,m+1,r,rt<<1|1);
    else return max(query(L,m,l,m,rt<<1),query(m+1,R,m+1,r,rt<<1|1));
}
int main() {
    int n , m;
    while (~scanf("%d%d",&n,&m)) {
        build(1 , n , 1);
        while (m --) {
            char op[2];
            int a , b;
            scanf("%s%d%d",op,&a,&b);
            if (op[0] == 'Q') printf("%d\n",query(a , b , 1 , n , 1));
            else update(a , b , 1 , n , 1);
        }
    }
    return 0;
}

( 2)线段树功能:update:单点增减 query:区间求和
敌兵布阵

#include <cstdio>
#include <algorithm>
#include<cstring>
#define mid ((l+r)>>1)
using namespace std;
const int MAXN=50010;
int sum[MAXN<<2];
void build(int l,int r,int rt)
{
    if(l==r)
    {
        scanf("%d",&sum[rt]);
        return;
    }
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int pos,int val,int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]+=val;
        return;
    }
    if(pos<=mid) update(pos,val,l,mid,rt<<1);
    else update(pos,val,mid+1,r,rt<<1|1);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r) return sum[rt];
    if(R<=mid) return query(L,R,l,mid,rt<<1);
    else if(mid+1<=L) return query(L,R,mid+1,r,rt<<1|1);
    else return query(L,mid,l,mid,rt<<1)+query(mid+1,R,mid+1,r,rt<<1|1);
}
int main()
{
    int t,n,L,R,val,pos;
    char order[10];
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++)
    {
        scanf("%d",&n);
        build(1,n,1);
        printf("Case %d:\n",cas);
        while(true)
        {
            scanf("%s",order);
            if(strcmp(order,"End")==0) break;
            else if(strcmp(order,"Query")==0)
            {
                scanf("%d%d",&L,&R);
                printf("%d\n",query(L,R,1,n,1));
            }
            else if(strcmp(order,"Add")==0)
            {
                scanf("%d%d",&pos,&val);
                update(pos,val,1,n,1);
            }
            else
            {
                scanf("%d%d",&pos,&val);
                update(pos,-val,1,n,1);
            }
        }
    }
    return 0;
}

求逆序数+离散化
( 3 )线段树功能:update:单点增减 query:区间求和
参考文档
Ultra-QuickSort
题意:
求解一个序列的逆序数

#include <cstdio>
#include<cstdlib>
#include<string.h>
#include <algorithm>
#define maxn  500010
using namespace std;
int segTree[maxn<<2],aa[maxn];
struct Node
{
    int val,id;
}arr[maxn];
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R) return segTree[rt];
    int mid=(l+r)>>1;
    int ret=0;
    if(L<=mid) ret+=query(L,R,l,mid,rt<<1);
    if(R>=mid+1) ret+=query(L,R,mid+1,r,(rt<<1)|1);
    return ret;
}
void update(int index,int l,int r,int rt)
{
    if(l==r)
    {
        segTree[rt]++;
        return;

    }
    int mid=(l+r)>>1;
    if(index<=mid) update(index,l,mid,rt<<1);
    else update(index,mid+1,r,(rt<<1)|1);
    segTree[rt]=segTree[rt<<1]+segTree[(rt<<1)|1];
}
int cmp(const void *a,const void * b)
{
    return (*(Node *)a).val-(*(Node *)b).val;
}
int main() {
    int n,i;
    while(scanf("%d",&n)!=EOF,n)
    {
        memset(segTree,0,sizeof(segTree));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&arr[i].val);
            arr[i].id=i;
        }
        qsort(arr+1,n,sizeof(Node),cmp);
        for(int i=1;i<=n;i++)
            aa[arr[i].id]=i;
        long long  sum=0;
        for(int i=1;i<=n;i++)
        {
            sum+=query(aa[i],n,1,n,1);
            update(aa[i],1,n,1);
        }
        printf("%lld\n",sum);
    }

}

Minimum Inversion Number

#include <cstdio>
#include<cstdlib>
#include<string.h>
#include <algorithm>
#define maxn  5005
using namespace std;
int segTree[maxn<<2],arr[maxn];
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R) return segTree[rt];
    int mid=(l+r)>>1;
    int ret=0;
    if(L<=mid) ret+=query(L,R,l,mid,rt<<1);
    if(R>=mid+1) ret+=query(L,R,mid+1,r,(rt<<1)|1);
    return ret;
}
void update(int index,int l,int r,int rt)
{
    if(l==r)
    {
        segTree[rt]++;
        return;

    }
    int mid=(l+r)>>1;
    if(index<=mid) update(index,l,mid,rt<<1);
    else update(index,mid+1,r,(rt<<1)|1);
    segTree[rt]=segTree[rt<<1]+segTree[(rt<<1)|1];
}
int main() {
    int n,i;
    while(scanf("%d",&n)!=EOF)
    {
        memset(segTree,0,sizeof(segTree));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&arr[i]);
        }
        int  sum=0;
        for(int i=1;i<=n;i++)
        {
            sum+=query(arr[i],n-1,0,n-1,1);
            update(arr[i],0,n-1,1);
        }
        int ret=sum;
        for(int i=1;i<=n;i++)
        {
            sum+=n-arr[i]-arr[i]-1;
            ret=min(sum,ret);
        }
        printf("%lld\n",ret);
    }
}

( 4 ) 题意:h*w的木板,放进一些1*L的物品,求每次放空间能容纳且最上边的位子
思路:每次找到最大值的位子,然后减去L
线段树功能:query:区间求最大值的位子(直接把update的操作在query里做了)

把每行看成线段树的叶子记录每片叶子的剩余空间,而根节点中保存的是叶子节点最大的剩余空间,每次判断给定的宽度从根节点能否插入,若左子数可以插则优先插入左子树,这样就可以保证每次插入都插在最上面。

Billboard

#include <cstdio>
#include<cstdlib>
#include<string.h>
#include <algorithm>
#define maxn  900010
using namespace std;
int segTree[maxn],w,h,n;
void build(int l,int r,int rt)
{
    segTree[rt]=w;
    if(l==r) return;
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
}
int query(int need,int l,int r,int rt)
{
    if(l==r)
    {
        segTree[rt]-=need;
        return l;
    }
    int ans,mid=(l+r)>>1;
    if(segTree[rt<<1]>=need) ans=query(need,l,mid,rt<<1);
    else ans=query(need,mid+1,r,rt<<1|1);
    segTree[rt]=max(segTree[rt<<1],segTree[rt<<1|1]);
    return ans;
}
int main() {
    int i,need;
    while(scanf("%d%d%d",&h,&w,&n)!=EOF)
    {
        h=min(h,n);
        build(1,h,1);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&need);
            if(segTree[1]<need) printf("-1\n");
            else printf("%d\n",query(need,1,h,1));
        }
    }
}

https://scut.online/problem.php?id=77
( 5 ) 题意:有两个操作:
1、将区间[ L,R ]里的所有数变为原来的一半。
2、询问区间 [ L,R ]的数之和,结果对1000000007取模。
n,m(n,m≤100000),n为点的个数,编号为1-n,m为操作次数
线段树功能:区间更新,区间求和。注意一个可以优化的地方:在query和update操作中,如果segTree[rt]==0,则不必递归下去了;不然容易超时。

#include<stdio.h>
#include <string.h>
using namespace std;
#define maxn 100010
typedef long long LL;
LL segTree[maxn<<2];
const LL mod=1000000007;
//void pushUp(int rt)
//{
//    segTree[rt]=(segTree[rt<<1]+segTree[(rt<<1)|1])%mod;
//}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        scanf("%lld",&segTree[rt]);
        return;
    }
    int mid=l+((r-l)>>1);
    build(l,mid,rt<<1);
    build(mid+1,r,(rt<<1)|1);
    segTree[rt]=(segTree[rt<<1]+segTree[(rt<<1)|1])%mod;
}
LL query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R) return segTree[rt];
    if(L<=l&&r<=R&&segTree[rt]==0) return 0;
    int mid=l+((r-l)>>1);
    LL sum=0;
    if(mid>=L) sum=(sum+query(L,R,l,mid,rt<<1))%mod;
    if(mid+1<=R) sum=(sum+query(L,R,mid+1,r,(rt<<1)|1))%mod;
    return sum;
}
void update(int L,int R,int l,int r,int rt)
{
    if(l==r)
    {
        segTree[rt]>>=1;
        return;
    }
    if(L<=l&&r<=R&&segTree[rt]==0) return;
    int mid=l+((r-l)>>1);
    if(L<=mid) update(L,R,l,mid,rt<<1);
    if(mid+1<=R) update(L,R,mid+1,r,(rt<<1)|1);
    segTree[rt]=(segTree[rt<<1]+segTree[(rt<<1)|1])%mod;
}
int main()
{
    int t,L,R;
    char op[5];
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,n,1);
        for(int i=1;i<=m;i++)
        {
            scanf("%s%d%d",op,&L,&R);
            if(op[0]=='A')
            {
                printf("%lld\n",query(L,R,1,n,1));
            }
            else
            {
                update(L,R,1,n,1);
            }
        }
    }
}

( 6 ) 线段树功能:update :区间增减 query:区间求和
题目大意:给定N个数的序列,有Q个操作。
操作分两种:
1、将某个区间内的所有数都加上某个数。
2、计算某个区间的所有数之和并输出。

方法一:逐点更新

我们有一个朴素的思路,更新区间时对区间内的所有点逐个更新

#include <cstdio>
#include <algorithm>
#include<cstring>
#define mid ((l+r)>>1)
using namespace std;
const int MAXN=100010;
long long sum[MAXN<<2];
void build(int l,int r,int rt)
{
    if(l==r)
    {
        scanf("%lld",&sum[rt]);
        return;
    }
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int L,int R,int l,int r,int rt,long long val)
{
    if(l==r)//对区间内的所有点逐个更新
    {
        sum[rt]+=val;
        return;
    }
    if(R<=mid) update(L,R,l,mid,rt<<1,val);
    else if(mid+1<=L) update(L,R,mid+1,r,rt<<1|1,val);
    else
    {
        update(L,mid,l,mid,rt<<1,val);
        update(mid+1,R,mid+1,r,rt<<1|1,val);
    }
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
long long query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r) return sum[rt];
    if(R<=mid) return query(L,R,l,mid,rt<<1);
    else if(mid+1<=L) return query(L,R,mid+1,r,rt<<1|1);
    return query(L,mid,l,mid,rt<<1)+query(mid+1,R,mid+1,r,rt<<1|1);
}
int main()
{
    int n,m,L,R;
    long long val;
    char op[5];
    scanf("%d%d",&n,&m);
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        scanf("%s",op);
        if(op[0]=='Q')
        {
            scanf("%d%d",&L,&R);
            printf("%lld\n",query(L,R,1,n,1));
        }
        else
        {
            scanf("%d%d%lld",&L,&R,&val);
            update(L,R,1,n,1,val);
        }
    }
    return 0;
}

但是,对每个点逐个进行更新,相当于暴力无疑,这样会很容易超时的,而且也体现不出线段树的优势!!!
所以需要进行延迟更新,延迟更新指等到调用update时或者查询时才更新节点的孩子的值

方法二 :延迟更新法

参考图例
A Simple Problem with Integers

#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn = 100010;
#define lson l,md,(rt<<1)
#define rson md+1,r,(rt<<1|1)
#define ls (rt<<1)
#define rs (rt<<1|1)
#define md ((l+r)>>1)
LL sum[maxn << 2], lazy[maxn << 2];
void up(int rt)
{
    sum[rt] = sum[ls] + sum[rs];
}
void down(int l, int r, int rt)//延迟标记向下(孩子节点)传递
{
    if (lazy[rt])
    {
        sum[ls] += (md - l + 1) * lazy[rt];//更新左孩子节点的val
        lazy[ls] += lazy[rt];//延迟标记向左孩子传递,以表明我左孩子节点已经更新了,
//但是!!左孩子的子节点还没更新呢!!!

        sum[rs] += (r - (md + 1) + 1) * lazy[rt];//更新右孩子
        lazy[rs] += lazy[rt];//延迟标记向右孩子传递,以表明我右孩子节点已经更新了,
//但是!!右孩子的子节点还没更新呢!!!

        lazy[rt] = 0;//当前节点已经更新过了,所以取消标记
    }
}
void build(int l, int r, int rt)
{
    lazy[rt] = 0;//初始化为0
    if (l == r)
    {
        scanf("%lld", &sum[rt]);
        return;
    }
    build(lson);
    build(rson);
    up(rt);
}
void update(int L, int R, int l, int r, int rt, LL val)
{
    if (L<=l&&R>=r)
    {
        sum[rt] += (r - l + 1) * val;
        lazy[rt] += val;
        return;
    }
    down(l, r, rt);//如果当前节点有延迟标记,那么更新一下节点的val以及传递延迟标记给孩子节点

    if (L <= md) update(L, R, lson, val);
    if (R > md) update(L, R, rson, val);
    up(rt);
}
LL query(int L, int R, int l, int r, int rt)
{
    if (L<=l&&R>=r) return sum[rt];
    down(l, r, rt);//如果当前节点有延迟标记,那么更新一下节点的val以及传递延迟标记给孩子节点
    LL sum = 0;
    if (L <= md) sum += query(L, R, lson);
    if (R > md) sum += query(L, R, rson);
    return sum;
}
int main() {
    int n, m, L, R;
    LL val;
    char op[5];
    scanf("%d%d", &n, &m);
    build(1, n, 1);
    for (int i = 1; i <= m; i++)
    {
        scanf("%s", op);
        if (op[0] == 'Q')
        {
            scanf("%d%d", &L, &R);
            printf("%lld\n", query(L, R, 1, n, 1));
        }
        else
        {
            scanf("%d%d%lld", &L, &R, &val);
            update(L, R, 1, n, 1, val);
        }
    }
    return 0;
}

方法三:
也是延迟更新但是有点不一样,具体请看代码

#include<cstdio>
#include <algorithm>
#define mid ((l+r)>>1)
using namespace std;
const int MAXN=100010;
long long sum[MAXN*4],mark[MAXN*4];
void build(int l,int r,int rt)
{
    sum[rt]=mark[rt]=0;
    if(l==r)
    {
        scanf("%lld",&sum[rt]);
        return;
    }
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int l,int r,int L,int R,int rt,int val)
{
    sum[rt]=sum[rt]+(R-L+1)*val;
    if(l==L&&R==r)
    {
        mark[rt]+=val;
        return;
    }
    if(R<=mid) update(l,mid,L,R,rt<<1,val);
    else if(L>mid) update(mid+1,r,L,R,rt<<1|1,val);
    else
    {
        update(l,mid,L,mid,rt<<1,val);
        update(mid+1,r,mid+1,R,rt<<1|1,val);
    }
}
long long query(int l,int r,int rt,int L,int R)
{
    if(L==l&&R==r) return sum[rt];
    long long ans=(R-L+1)*mark[rt];
    if(R<=mid) ans+=query(l,mid,rt<<1,L,R);
    else if(L>mid) ans+=query(mid+1,r,rt<<1|1,L,R);
    else
    {
        ans+=query(l,mid,rt<<1,L,mid);
        ans+=query(mid+1,r,rt<<1|1,mid+1,R);
    }
    return ans;
}
int main()
{
    int n,m,L,R;
    long long  val;
    char op[5];
    scanf("%d%d",&n,&m);
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        scanf("%s",op);
        if(op[0]=='Q')
        {
            scanf("%d%d",&L,&R);
            printf("%lld\n",query(1,n,1,L,R));
        }
        else
        {
            scanf("%d%d%lld",&L,&R,&val);
            update(1,n,L,R,1,val);
        }
    }
    return 0;
}

( 7 ) 线段树功能: update:区间替换 ,query:区间求和
Just a Hook
题意:
一段线段由n条小线段组成,每次操作把一个区间的小线段变成金银铜之一(金的价值为3,银为2,铜为1),最初可当做全为铜;最后求这条线段的总价值。

#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=100010;
#define lson l,md,(rt<<1)
#define rson md+1,r,(rt<<1|1)
#define ls (rt<<1)
#define rs (rt<<1|1)
#define md ((l+r)>>1)
LL sum[maxn<<2],lazy[maxn<<2];
void up(int rt)
{
    sum[rt]=sum[ls]+sum[rs];
}
void down(int l,int r,int rt)
{
    if(lazy[rt])
    {
        sum[ls]=(md-l+1)*lazy[rt];
        lazy[ls]=lazy[rt];

        sum[rs]=(r-(md+1)+1)*lazy[rt];
        lazy[rs]=lazy[rt];

        lazy[rt]=0;
    }
}
void build(int l,int r,int rt)
{
    lazy[rt]=0;
    if(l==r)
    {
        sum[rt]=1;
        return;
    }
    build(lson);
    build(rson);
    up(rt);
}
void update(int L,int R,int l,int r,int rt,LL val)
{
    if(L==l&&r==R)
    {
        sum[rt]=(R-L+1)*val;
        lazy[rt]=val;
        return;
    }
    down(l,r,rt);

    if(md>=R) update(L,R,lson,val);
    else if(md+1<=L) update(L,R,rson,val);
    else{
        update(L,md,lson,val);
        update(md+1,R,rson,val);
    }
    up(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
    if(L==l&&r==R) return sum[rt];
    down(l,r,rt);
    if(md>=R) return query(L,R,lson);
    else if(md+1<=L) return query(L,R,rson);
    return query(L,md,lson)+query(md+1,R,rson);
}
int main() {
    int t,n,m,L,R;
    LL val;
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++)
    {
        scanf("%d%d",&n,&m);
        build(1,n,1);
        while(m--)
        {
            scanf("%d%d%lld",&L,&R,&val);
            update(L,R,1,n,1,val);
        }
        printf("Case %d: The total value of the hook is %lld.\n",cas,query(1,1,1,1,1));
    }
    return 0;
}

https://vjudge.net/problem/HDU-1698
( 7 ) 线段树功能: update:区间变为原来的b次方 ,query:区间乘积
题意:操作1: l ,r ,b : 把k∈[l,r] 的妹子, 能力值 ak变成ak^b
操作2:l , r : 求累乘 ∏(l⩽k⩽r)ak
题解:a^k ≡ a^(k mod (p−1)) mod p , p是素数.

#include<cstdio>
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=100020;
const LL mod=1000000007;
#define lson l,md,(rt<<1)
#define rson md+1,r,(rt<<1|1)
#define md ((l+r)>>1)
#define ls (rt<<1)
#define rs (rt<<1|1)
LL sum[maxn<<2],lazy[maxn<<2];
LL pow_mod(LL a,int b)
{
    LL res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}
void up(int rt)
{
    sum[rt]=sum[ls]*sum[rs]%mod;
}
void down(int l,int r,int rt)
{
     if(lazy[rt]!=1)
    {
        sum[ls]=pow_mod(sum[ls],lazy[rt]);
        lazy[ls]=lazy[ls]*lazy[rt]%(mod-1);

        sum[rs]=pow_mod(sum[rs],lazy[rt]);
        lazy[rs]=lazy[rs]*lazy[rt]%(mod-1);

        lazy[rt]=1;
    }
}
void update(int L,int R,int l,int r,int rt,int b)
{
    if(L==l&&r==R)
    {
        sum[rt]=pow_mod(sum[rt],b);
        lazy[rt]=lazy[rt]*b%(mod-1);
        return;
    }
    down(l,r,rt);
    if(R<=md) update(L,R,lson,b);
    else if(L>md) update(L,R,rson,b);
    else{
        update(L,md,lson,b);
        update(md+1,R,rson,b);
    }
    sum[rt]=sum[ls]*sum[rs]%mod;
}
LL query(int L,int R,int l,int r,int rt)
{
    if(L==l&&r==R) return sum[rt];
    down(l,r,rt);
    if(R<=md) return query(L,R,lson);
    else if(L>md) return query(L,R,rson);
    return query(L,md,lson)*query(md+1,R,rson)%mod;
}
void build(int l,int r,int rt)
{
    lazy[rt]=1;
    if(l==r)
    {
        scanf("%lld",&sum[rt]);
        return ;
    }
    build(lson);
    build(rson);
    sum[rt]=sum[ls]*sum[rs]%mod;
}
int main() {
    int t,n,m;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &n, &m);
        build(1, n, 1);
        while(m--) {
            int op, l, r, b;
            scanf("%d%d%d", &op, &l, &r);
            if(op == 1) {
                scanf("%d", &b);
                update(l,r,1,n,1,b);
            }
            else {
                LL ans = query(l,r,1,n,1);
                printf("%lld\n", ans);
            }
        }
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • created by Dejavu(不断更新中) 概念 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条...
    ericdejavu阅读 1,133评论 0 0
  • 转自:http://www.cnblogs.com/TenosDoIt/p/3453089.html#b 一 概述...
    碧影江白阅读 1,542评论 1 2
  • 待更新 线段树讲解(未读)线段树模板(未读) 模板 求区间总和 A - 敌兵布阵 HDU - 1166 题意 线段...
    染微言阅读 1,284评论 1 0
  • 在已知了树状数组的使用方法,那么便可以用它来解决一些实际问题了,比如说下面一道经典题:敌兵布阵 :HDU:1166...
    碧影江白阅读 1,065评论 0 2
  • 很多人在写c语言程序的时候,经常分不清两者的区别,到底该定义signed char还是unsigned char呢...
    CodingCode阅读 2,558评论 0 1