zoukankan      html  css  js  c++  java
  • 寒假Day43:HDU1540 Tunnel Warfare 线段树+区间合并

    题意

    给出n个相邻的村庄,q个操作

    D代表损坏一个村庄

    R代表修复村庄

    Q代表查询给定的村庄和多少个村庄相邻

    思路

    反正我还是没有想通为什么是用线段树这个算法来解决的。

    AC代码

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<stack>
    typedef long long ll;
    using namespace std;
    const int N=5e4+20;
    #define inf 0x3f3f3f3f
    
    int lsum[N<<2],rsum[N<<2],n;
    
    void build(int L,int R,int i)
    {
        lsum[i]=rsum[i]=R-L+1;
        if(L==R)
            return;
        int mid=(L+R)>>1;
        build(L,mid,i<<1);
        build(mid+1,R,i<<1|1);
    }
    
    //update(1,n,1,w,0);  flag:repair 0;restory 1
    void update(int l,int r,int i,int x,int flag)
    {
        if(l==r&&flag)
            lsum[i]=rsum[i]=0;
        if(l==r&&flag==0)
            lsum[i]=rsum[i]=1;
        if(l==r)
            return ;
        int mid=(l+r)>>1;
        if(x<=mid)
            update(l,mid,i<<1,x,flag);
        else
            update(mid+1,r,i<<1|1,x,flag);
        int len=r-l+1;
        lsum[i]=lsum[i<<1];
        rsum[i]=rsum[i<<1|1];
        if(lsum[i]==len-(len>>1))
            lsum[i]+=lsum[i<<1|1];
        if(rsum[i]==(len>>1))
            rsum[i]+=rsum[i<<1];
    }
    
    //query(1,n,1,x)
    int query(int l,int r,int i,int x)
    {
        if(l==r)
            return lsum[i];
        int ans=-inf,L=l+lsum[i]-1,R=r-rsum[i]+1;
        if(l<=x&&x<=L)//在左边
            ans=max(ans,lsum[i]);
        if(R<=x&&x<=r)//在右边
            ans=max(ans,rsum[i]);
        int mid=(l+r)>>1;
        if(mid-rsum[i<<1]+1<=x&&x<=mid+lsum[i<<1|1])
            ans=max(ans,lsum[i<<1|1]+rsum[i<<1]);
        if(ans!=-inf)
            return ans;
        if(x<=mid)
            return query(l,mid,i<<1,x);
        return query(mid+1,r,i<<1|1,x);
    }
    
    int main()
    {
        int q,x;
        while(~scanf("%d %d",&n,&q))
        {
            build(1,n,1);
            stack<int>s;
            for(int i=1; i<=q; i++)
            {
                char ch[2];
                scanf("%s",ch);
                if(ch[0]=='D')//destory
                {
                    scanf("%d",&x);
                    s.push(x);
                    update(1,n,1,x,1);
                }
                else if(ch[0]=='Q')//查询相连个数
                {
                    scanf("%d",&x);
                    int w=query(1,n,1,x);
                    printf("%d\n",w);
                }
                else if(ch[0]=='R')//repair
                {
                    int w=s.top();
                    update(1,n,1,w,0);
                    s.pop();
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    左侧导航太长了?
    组织结构配置文件的诡异行为
    SharePoint上无法显示Lync的在线状态
    多语言和自定义CSS
    文档库下载副本,文件名被截断
    在线menu生成网站
    FC7崩溃,安装Ubuntu,相当不错的系统
    简易下载baidu音乐排行榜音乐
    java放射调用静态方法和构造函数
    升级到Ubuntu7.10导致Eclipse中键盘无效的问题
  • 原文地址:https://www.cnblogs.com/OFSHK/p/12430652.html
Copyright © 2011-2022 走看看