设为首页 加入收藏

TOP

HDU4638[离线树状数组]
2014-11-23 19:18:57 来源: 作者: 【 】 浏览:11
Tags:HDU4638

分析问题并考虑已知的数据结构。

细节处理很重要。

#include    
#include    
#include    
#include    
#include    
using namespace std;  
//用标记数组的话果然不对  比如样例3 1 2 5 4,走一遍之后,再从头开始进行遍历的话,3+1,3-1都有标记,后面的都加了1   
//还有得注意到底是什么情况下用sum(a)-sum(b);什么情况下只用sum(a)就够了   
//树状数组更新之后 其后所有的数都会更新 切记   
int a[100005];  
int visit[100005];  
int c[100005];  
int ret[100005];  
int num[100005];  
struct vv  
{  
    int l,r;  
    int id;  
}v[100005];  
int max(int a,int b)  
{  
    if(a=1;i-=lowbit(i))  
        ret+=c[i];  
    return ret;  
}  
int main()  
{  
    int case_num;  
    scanf("%d",&case_num);  
    while(case_num--)  
    {  
        memset(c,0,sizeof(c));  
        memset(num,0,sizeof(num));  
        int n,m;  
        scanf("%d%d",&n,&m);  
        for(int i = 1;i <= n;i++)  
        {  
            scanf("%d",&a[i]);  
            num[a[i]]=i;  
        }  
        num[0] = n+10;  
        num[n+1] = n+10;  
        for(int i = 1;i <= n;i++)  
        {  
            if(i < num[a[i]-1] && i < num[a[i]+1])     //d段数加1   
                update(i,1);  
            else if(i > num[a[i]-1] && i > num[a[i]+1])   //段数减1   
                update(i,-1);  
        }  
        for(int i=0;i num[a[i]-1] && i > num[a[i]+1])   //删除a[i],则把原来加的一,减去   
                    update(i,-1);  
                else if(i < num[a[i]-1] && i < num[a[i]+1])  
                {  
                    int Min = min(num[a[i]-1],num[a[i]+1]);  
                    int Max = max(num[a[i]-1],num[a[i]+1]);  
                    update(i,-1);               //愿来加的一减去   
                    update(Min,1);              //少了a[i],则相应段数增加   
                    update(Max,1);              // . ...   
                }  
                else if(i < num[a[i]-1])  
                {  
                    update(i,-1);  
                    update(num[a[i]-1],1);  
                }  
                else  
                {  
                    update(i,-1);  
                    update(num[a[i]+1],1);  
                }  
                i++;  
            }  
                ret[v[j].id]= sum(v[j].r); //保存答案   
                j++;  
        }  
        for(int i=0;i
#include 
#include 
#include 
#include 
using namespace std;
//用标记数组的话果然不对  比如样例3 1 2 5 4,走一遍之后,再从头开始进行遍历的话,3+1,3-1都有标记,后面的都加了1
//还有得注意到底是什么情况下用sum(a)-sum(b);什么情况下只用sum(a)就够了
//树状数组更新之后 其后所有的数都会更新 切记
int a[100005];
int visit[100005];
int c[100005];
int ret[100005];
int num[100005];
struct vv
{
    int l,r;
    int id;
}v[100005];
int max(int a,int b)
{
    if(a=1;i-=lowbit(i))
        ret+=c[i];
    return ret;
}
int main()
{
    int case_num;
    scanf("%d",&case_num);
    while(case_num--)
    {
        memset(c,0,sizeof(c));
        memset(num,0,sizeof(num));
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++)
        {
            scanf("%d",&a[i]);
            num[a[i]]=i;
        }
        num[0] = n+10;
        num[n+1] = n+10;
        for(int i = 1;i <= n;i++)
        {
            if(i < num[a[i]-1] && i < num[a[i]+1])     //d段数加1
                update(i,1);
            else if(i > num[a[i]-1] && i > num[a[i]+1])   //段数减1
                update(i,-1);
        }
        for(int i=0;i num[a[i]-1] && i > num[a[i]+1])   //删除a[i],则把原来加的一,减去
                    update(i,-1);
                else if(i < num[a[i]-1] && i < num[a[i]+1])
                {
                    int Min = min(num[a[i]-1],num[a[i]+1]);
                    int Max = max(num[a[i]-1],num[a[i]+1]);
                    update(i,-1);               //愿来加的一减去
                    update(Min,1);              //少了a[i],则相应段数增加
                    update(Max,1);              // . ...
                }
                else if(i < num[a[i]-1])
                {
                    update(i,-1);
                    update(num[a[i]-1],1);
                }
                else
                {
                    update(i,-1);
                    update(num[a[i]+1],1);
                }
                i++;
            }
                ret[v[j].id]= sum(v[j].r); //保存答案
                j++;
        }
        for(int i=0;i 
 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇POJ 1743 Musical Theme(后缀数.. 下一篇shell more less cat

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·求navicat for mysql (2025-12-26 13:21:33)
·有哪位大哥推荐一下m (2025-12-26 13:21:30)
·MySQL下载与安装教程 (2025-12-26 13:21:26)
·Linux_百度百科 (2025-12-26 12:51:52)
·Shell 流程控制 | 菜 (2025-12-26 12:51:49)