2015 UESTC 数据结构专题A题 秋实大哥与小朋友 线段树 区间更新,单点查询,离散化

秋实大哥与小朋友

Time Limit: 1 Sec  Memory Limit: 256 MB

题目连接

http://acm.uestc.edu.cn/#/contest/show/59

Description

秋实大哥以周济天下,锄强扶弱为己任,他常对天长叹:安得广厦千万间,大庇天下寒士俱欢颜。

所以今天他又在给一群小朋友发糖吃。

他让所有的小朋友排成一行,从左到右标号。在接下去的时间中,他有时会给一段区间的小朋友每人v颗糖,有时会问第x个小朋友手里有几颗糖。

这对于没上过学的孩子来说实在太困难了,所以你看不下去了,请你帮助小朋友回答所有的询问。

Input

第一行包含两个整数n,m,表示小朋友的个数,以及接下来你要处理的操作数。

接下来的m行,每一行表示下面两种操作之一:

0 l r v : 表示秋实大哥给[l,r]这个区间内的小朋友每人v颗糖

1 x : 表示秋实大哥想知道第x个小朋友手里现在有几颗糖

1≤m,v≤100000,1≤l≤r≤n,1≤x≤n,1≤n≤100000000。 1xn1n100000000

Output

对于每一个1 x操作,输出一个整数,表示第x个小朋友手里现在的糖果数目。
 

Sample Input

3 4
0 1 3 1
1 2
0 2 3 3
1 3

Sample Output

1
4

HINT


题意


题解:

灰常简单的一个区间更新+单点查询问题,但是n比较大!比较大!肿么办?
这位 小彭玉请告诉我,肿么办?
哈,我们先把数读进来,然后排个序,维护个前缀和,或者来个map,就可以离散化啦!
我真是机智呀!

代码:

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=100000*5;
typedef long long LL;

struct node
{
    int lft,rht;
    LL sum,add;
    int mid(){return MID(lft,rht);}
    void fun(LL tmp)
    {
        add+=tmp;
        sum+=(rht-lft+1)*tmp;
    }
};

int y[N];

struct Segtree
{
    node tree[N*4];
    void relax(int ind)
    {
        if(tree[ind].add)
        {
            tree[LL(ind)].fun(tree[ind].add);
            tree[RR(ind)].fun(tree[ind].add);
            tree[ind].add=0;
        }
    }
    void build(int lft,int rht,int ind)
    {
        tree[ind].lft=lft;    tree[ind].rht=rht;
        tree[ind].sum=0;    tree[ind].add=0;
        if(lft==rht) tree[ind].sum=y[lft];
        else
        {
            int mid=tree[ind].mid();
            build(lft,mid,LL(ind));
            build(mid+1,rht,RR(ind));
            tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;
        }
    }
    void updata(int st,int ed,int ind,int add)
    {
        int lft=tree[ind].lft,rht=tree[ind].rht;
        if(st<=lft&&rht<=ed) tree[ind].fun(add);
        else
        {
            relax(ind);
            int mid=tree[ind].mid();
            if(st<=mid) updata(st,ed,LL(ind),add);
            if(ed> mid) updata(st,ed,RR(ind),add);
            tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;
        }
    }
    LL query(int st,int ed,int ind)
    {
        int lft=tree[ind].lft,rht=tree[ind].rht;
        if(st<=lft&&rht<=ed) return tree[ind].sum;
        else
        {
            relax(ind);
            int mid=tree[ind].mid();
            LL sum1=0,sum2=0;
            if(st<=mid) sum1=query(st,ed,LL(ind));
            if(ed> mid) sum2=query(st,ed,RR(ind));
            return sum1+sum2;
        }
    }
}seg;
int kiss[100000*5];
int dow[100000*5];
struct oi
{
    int x,y,c,id,ty;
};
oi ans[100000*5];
int tot1,tot2=1;
int getid(int x)
{
    int l=1,r=tot2;
    int mid=(l+r)>>1;
    while(dow[mid]!=x&&dow[l]!=x&&dow[r]!=x)
    {
        mid=(l+r)>>1;
        if(dow[mid]>x)
            r=mid;
        else
            l=mid+1;
    }
    if(dow[mid]==x)
        return mid;
    if(dow[l]==x)
        return l;
    if(dow[r]==x)
        return r;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        char str[5];
        int a,b,c;
        memset(y,0,sizeof(y));
        seg.build(1,100000*3,1);
        for(int i=0;i<m;i++)
        {
            scanf("%s",str);
            if(str[0]=='1')
            {
                scanf("%d",&a);
                ans[i].x=a,ans[i].y=a,ans[i].c=1,ans[i].id=i,ans[i].ty=-1;
                kiss[tot1++]=a;
            }
            else
            {
                scanf("%d%d%d",&a,&b,&c);
                ans[i].x=a,ans[i].y=b,ans[i].c=c,ans[i].id=i,ans[i].ty=1;
                kiss[tot1++]=a;
                kiss[tot1++]=b;
            }
        }
        tot2=0;
        sort(kiss,kiss+tot1);
        for(int i=0;i<tot1;i++)
            if(dow[tot2]!=kiss[i])
                dow[++tot2]=kiss[i];


        for(int i=0;i<m;i++)
        {
            if(ans[i].ty==-1)
            {
                int x=getid(ans[i].x);
                printf("%lld\n",seg.query(x,x,1));
            }
            else
            {
                int x=getid(ans[i].x),y=getid(ans[i].y),z=ans[i].c;
                seg.updata(x,y,1,z);
            }
        }
    }
    return 0;
}

 

你可能感兴趣的:(数据结构)