文章标题 HDU 1754 : I Hate It (分块 、线段树)

来源:互联网 发布:sql server2012破解版 编辑:程序博客网 时间:2024/06/05 13:29

I Hate It

分块解法:
代码:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <queue>#include <set>#include <map>#include <algorithm>#include <math.h>#include <vector>using namespace std;typedef long long ll;const int mod=1e9+7;const int maxn=2e5+10;int block;//块的大小 int belong[maxn];//belong[i]表示i属于那一块 int l[maxn],r[maxn];//表示这块的左端点的位置和右端点的位置int num;//块的个数 int n,m;ll a[maxn]; ll Max[maxn];void build(){    block=sqrt(n);    num=n/block;if (n%block)num++;    for (int i=1;i<=num;i++){        l[i]=(i-1)*block+1; r[i]=i*block;//每个块的左右端点的位置     }    r[num]=n;    for (int i=1;i<=n;i++){        belong[i]=(i-1)/block+1;    }    //---------上面是预处理    //下面根据题目进行预处理     for (int i=1;i<=num;i++){        Max[i]=0;        for (int j=l[i];j<=r[i];j++){            Max[i]=max(Max[i],a[j]);        }    }}void update(int pos,int val){    a[pos]=val;    Max[belong[pos]]=max(Max[belong[pos]],a[pos]);}ll query(int x,int y){    ll ans = 0;    if (belong[x]==belong[y]){//同属一块直接暴力         for (int i=x;i<=y;i++)ans = max(ans,a[i]);        return ans;    }    for (int i=x;i<=r[belong[x]];i++){//左边 多出部分         ans=max(ans,a[i]);     }    for (int i=belong[x]+1;i<belong[y];i++){//中间的块         ans=max(ans,Max[i]);    }     for (int i=l[belong[y]];i<=y;i++){//右边多出部分         ans = max (ans,a[i]);    }    return ans;}char s[10];int main(){    while (scanf ("%d%d",&n,&m)!=EOF){        for (int i=1;i<=n;i++){            scanf ("%lld",&a[i]);        }        build();         int x,y;        while (m--){            scanf ("%s",s);            scanf ("%d%d",&x,&y);            if (s[0]=='U'){                update(x,y);            }else {                printf ("%lld\n",query(x,y));            }        }    }     return 0;}

线段树解法

#include<iostream>#include<string>#include<cstdio>#include<cstring>#include<vector>#include<math.h>#include<queue> #include<algorithm>using namespace std;int n,m;int Max[200005*4];void build_tree(int node,int left,int right){    if (left==right){        scanf ("%d",&Max[node]);    }    else {        int mid=(left+right)>>1;        build_tree(node*2,left,mid);        build_tree(node*2+1,mid+1,right);        Max[node]=max(Max[node*2],Max[node*2+1]);     }} int ql,qr;int query(int node,int left,int right){    int ans=-1;    int mid=(left+right)/2;    if (ql<=left&&right<=qr) return Max[node];    if (qr<=mid) return query(node*2,left,mid);    else if (ql>mid) return query(node*2+1,mid+1,right);    else {        return max(query(node*2,left,mid),query(node*2+1,mid+1,right));    }}int val;//将分数改为该值 int place;//学生的位置 void update(int node,int left,int right){    int mid=(left+right)/2;    if (left==right) Max[node]=val;    else {        if (place<=mid){            update(node*2,left,mid);        }        else {            update(node*2+1,mid+1,right);        }        Max[node]=max(Max[node*2],Max[node*2+1]);    }}int main (){    while (scanf ("%d%d",&n,&m)!=EOF){        build_tree(1,1,n);        char order[10];        for (int i=0;i<m;i++){            scanf ("%s",order);            if (order[0]=='Q'){                int a,b;                scanf ("%d%d",&ql,&qr);                printf ("%d\n",query(1,1,n));            }            else if (order[0]=='U'){                scanf ("%d%d",&place,&val);                update(1,1,n);            }        }    }           return 0;}
原创粉丝点击