zoukankan      html  css  js  c++  java
  • Tunnel Warfare HDU

    题目链接 点此跳转
    题意:单点修改,每次询问输入x,求包含x的最长连续区间
    分析:直接暴力分块(相当于三层的树),时间复杂度O(n*sqrt(n) )
    坑点:多组输入
    Time:390ms
    Memory:1792kB
    AC代码

    #include<bits/stdc++.h>
    using namespace std;///hdu 1540 暴力分块
    const int N=50005;
    struct node
    {
        int l,r,v;
    };
    node bk[N];///block 相当于根号n叉树
    int bl[N],a[N],tot,ans; ///bl[] belong,表示属于哪个块,a[]就是单个结点
    stack<int> sta; ///储存最后一次“毁灭”
    int size,n,m;
    int read()///快读
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch) )
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(isdigit(ch) )
        {
            x=10*x+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    void init()///分块
    {
        while(!sta.empty() ) sta.pop();
        size=sqrt(n);
        tot=n/size;
        for(int i=1;i<=n;i++)
        {
            a[i]=1;
            bl[i]=(i-1)/size+1;
        }
        for(int i=1;i<=tot;i++)
        {
            bk[i].l=(i-1)*size+1;
            bk[i].r=i*size;
            bk[i].v=size;
        }
        if(tot*size<n)
        {
            bk[++tot].l=(tot-1)*size+1;
            bk[tot].r=n;
            bk[tot].v=n-bk[tot].l+1;
        }
    }
    void query(int x)
    {
        int t=bl[x];
        int t1=x,t2=x-1;
        while(t1<=bk[t].r&&a[t1] ) ans++,t1++;///计算当前块
        while(t2>=bk[t].l&&a[t2] ) ans++,t2--;
        if(t1>bk[t].r)///向外拓展
        {
            t1=t+1;
            while(t1<=tot&&bk[t1].v==bk[t1].r-bk[t1].l+1) ans+=bk[t1++].v;///整块整块的算
            if(t1<=tot)///整块的算完了,开始算单个的连续的结点
            {
                int i=bk[t1].l;
                while(i<=bk[t1].r&&a[i] ) ans++,i++;
            }
        }
        if(t2<bk[t].l)
        {
            t2=t-1;
            while(t2>=1&&bk[t2].v==bk[t2].r-bk[t2].l+1) ans+=bk[t2--].v;
            if(t2>=1)
            {
                int i=bk[t2].r;
                while(i>=bk[t2].l&&a[i] ) ans++,i--;
            }
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init();
            while(m--)
            {
                char cmd[5];
                scanf("%s",cmd);
                if(cmd[0]=='D')
                {
                    int x=read();
                    int t=bl[x];
                    if(a[x])
                        bk[t].v--;
                    a[x]=0;
                    sta.push(x);
                }
                else if(cmd[0]=='Q')
                {
                    int x=read();
                    ans=0;
                    if(a[x]) query(x);
                    printf("%d
    ",ans);
                }
                else if(!sta.empty() )
                {
                    int x=sta.top();///取最后一次毁灭命令
                    sta.pop();
                    a[x]=1;
                    int t=bl[x];
                    bk[t].v++;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Linux新手入门:通过chmod改变文件权限
    Android Activity 以及 Application 生命周期
    java 并发库之 Executors
    java Netty tcp通讯
    Android App 切换语言
    java svg转png
    高效的数独算法-位运算
    Android 高效的`InjectView – ButterKnife`
    Android 监听文件夹
    Android 更新UI
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12025217.html
Copyright © 2011-2022 走看看