• hdu 1540 Tunnel Warfare


    题意:给你一个完整的1~n区间,他们是连续的,D代表破坏某个村庄,Q代表询问这个村庄何其他几何村庄相连,R代表修复村庄

    思路:并不会用线段树维护区间,之前卡了好久,直到自己把样例画出来(还是太懒了),这才明白线段树维护区间的意思,,然后参照大牛的博客才水过

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=50000+10;
    int lsum[maxn<<2],rsum[maxn<<2];
    int s[maxn],top,n,m,a;
    char ch[2];
    bool mark[maxn];
    
    void pushdown(int i,int len)
    {
        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];
    }
    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);
    }
    void update(int p,int date,int l,int r,int i)
    {
        if(l==r){
            rsum[i]+=date;
            lsum[i]=rsum[i];
            return ;
        }
        int mid=(l+r)>>1;
        if(p<=mid)update(p,date,l,mid,i<<1);
        else update(p,date,mid+1,r,i<<1|1);
        pushdown(i,r-l+1);
    }
    
    int queryL(int L,int R,int l,int r,int i)
    {
        if(L<=l&&r<=R){
            return lsum[i];
        }
        int mid=(l+r)>>1;
        if(R<=mid)queryL(L,R,l,mid,i<<1);
        else if(mid<L)queryL(L,R,mid+1,r,i<<1|1);
        else{
            int lans=queryL(L,mid,l,mid,i<<1);
            int rans=queryL(mid+1,R,mid+1,r,i<<1|1);
            if(lans==mid-L+1)return lans+rans;
            return lans;
        }
    }
    int queryR(int L,int R,int l,int r,int i)
    {
        if(L<=l&&r<=R){
            return rsum[i];
        }
        int mid=(l+r)>>1;
        if(R<=mid)queryR(L,R,l,mid,i<<1);
        else if(mid<L)queryR(L,R,mid+1,r,i<<1|1);
        else{
            int lans=queryR(L,mid,l,mid,i<<1);
            int rans=queryR(mid+1,R,mid+1,r,i<<1|1);
            if(rans==R-mid)return lans+rans;
            return rans;
        }
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            build(1,n,1);
            memset(mark,false,sizeof(mark));
            mark[0]=true,top=0;
            for(int i=0;i<m;i++){
                scanf("%s",ch);
                if(ch[0]=='D'){
                    scanf("%d",&a);
                    s[++top]=a;
                    if(!mark[a])update(a,-1,1,n,1),mark[a]=true;
                }
                else if(ch[0]=='R'){
                    while(!mark[s[top]])--top;
                    if(top)update(s[top],1,1,n,1),mark[s[top--]]=false;
                }
                else{
                    scanf("%d",&a);
                    int temp=queryL(a,n,1,n,1)+queryR(1,a,1,n,1);
                    printf("%d
    ",temp>0?temp-1:0);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    用Iterator实现遍历集合
    SimpleDateFormat使用详解 <转>
    Java学习之Iterator(迭代器)的一般用法 (转)
    Java:String和Date、Timestamp之间的转换
    关于PreparedStatement.addBatch()方法 (转)
    JavaBean入门及简单的例子
    Tomcat7.0无法启动解决方法[failed to start]
    executeQuery、executeUpdate 和 execute
    jquery中attr和prop的区别
    Jquery的parent和parents(找到某一特定的祖先元素)
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/8467786.html
Copyright © 2020-2023  润新知