A.Ocean的礼物线段树

A: Ocean的礼物 
Time Limit: 2 s Memory Limit: 128 MB 
Submit My Status 
Problem Description 
皇家理工存在一段很神奇的路段,这段路由nn个格子组成,每个格子都有一个数字,你可以走这段路的任意一段。这段路的神奇之处就在于,如果你所处的这个格子数字和你经过的前一个格子数字不相同的话,你就可以获得一个礼物(初始一定可以获得礼物)。现在Ocean想知道,给定任意路段的左边界和右边界,问若走这段路可以获得多少礼物。不过幸运的是,Ocean很快就解决了,并且获得了大量的礼物。玩的十分开心。但是有一天,这段路神奇的发生了改变。它不但会给你礼物。它还可能随时的改变其任意某处的格子上的数字。这下Ocean可就犯愁了,他想知道任意一段路可以获得的礼物是多少。聪明的你可以帮下他吗?

Input 
第一行输入一个整数nn,代表格子数。(1≤n≤106)(1≤n≤106) 
第二行输入nn个整数xx。(1≤x≤108)(1≤x≤108) 
第三行输入一个整数mm,代表mm次操作。(1≤m≤2∗105)(1≤m≤2∗105) 
接下来第四行到3+m3+m行每行33个数op,x,yop,x,y。

若op=1op=1则把xx处的数修改为yy。(1≤x≤n,1≤y≤108)(1≤x≤n,1≤y≤108) 
若op=2op=2,询问区间[x,y][x,y]内可以获得的礼物数。(1≤x≤y≤n)(1≤x≤y≤n) 
Output 
对于每个询问输出一个整数,代表可以获得的礼物数

Sample Input 

1 2 3 4 5 6 

2 1 6 
1 2 3 
2 2 3 
2 3 4 
Sample Output 


2

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int cnt,a[1111111];
struct node
{
    int l,r,val;
}p[2222222];
void pushup(int i)
{
    p[i].val=p[i<<1].val+p[i<<1|1].val;
}
void build(int i,int x,int y)
{
    p[i].l=x;
    p[i].r=y;
    if(p[i].r==p[i].l)
    {
        int pos=p[i].l;
        if(a[pos]!=a[pos-1]||pos==1)
            p[i].val=1;
        else p[i].val=0;
        return;
    }
    int m=p[i].r+p[i].l>>1;
    build(i<<1,x,m);
    build(i<<1|1,m+1,y);
    pushup(i);
}
void update(int i,int x,int val)
{
    if(p[i].l==p[i].r)
    {
        p[i].val=val;
        return;
    }
    int m=p[i].r+p[i].l>>1;
    if(x<=m)
        update(i<<1,x,val);
    if(x>m)
        update(i<<1|1,x,val);
    pushup(i);
}
void query(int i,int x,int y)
{
    if(p[i].l>=x&&p[i].r<=y)
    {
        cnt+=p[i].val;
        return;
    }
    int m=p[i].l+p[i].r>>1;
    if(x<=m)
        query(i<<1,x,y);
    if(y>m)
        query(i<<1|1,x,y);
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    build(1,1,n);
    int Q;
    scanf("%d",&Q);
    while(Q--)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(x==1)
        {
            a[y]=z;
            if(y>1)
            {
                if(a[y]==a[y-1])
                    update(1,y,0);
                else
                    update(1,y,1);
            }
            if(y<n)
            {
                if(a[y]==a[y+1])
                    update(1,y+1,0);
                else
                    update(1,y+1,1);
            }
        }
        if(x==2)
        {
            cnt=1;
            query(1,y+1,z);
            printf("%d\n",cnt);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42060896/article/details/81661683