poj3321 树状数组

这几天在看杭电马拉松的题,我都无语啦,其中有一个是晒被子的问题,我看了大牛的思路然后写的超时了,然后我看了别人的代码,结果一直WA,后来几乎代码改了一样的但还是WA,后来找了一晚上的错误,然后发现了大牛的代码是在g++环境中运行的,而我用的是VC++编译器,然后就是对max()的这个函数他的是库函数而我的是自己写的,而错误就在这里,我都被这些弄糊涂了,结果我的一直还是没有过,脑袋大了!

对于这道题,我又犯了一个想投机取巧的错误,就是像建立树来着,那是没有考虑特殊情况,TLE了,后来看了别人的建立树状数组,几乎看了别人的代码的。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
using namespace std;
#define ll __int64
#define rep(i,n) for(i=0; i<(n); i++) 
#define reph(i,n,m) for(i=(n); i<=(m); i++)//正循环的
#define repd(i,n,m) for(i=(n); i>=(m); i--) //负循环的 
#define fab(a) (a)>0?(a):0-(a)
#define arc(a) (a)*(a)
#define inf 10000000   //最大值的
#define exp 0.0000001     //浮点型的
#define N 100010
typedef struct fun
{
        int y;
        int pre;
        }rr;
typedef struct point
{
        int low,high;
}ee;
point b[N];
fun a[N];
int sum[N];
int pre[N];
int n,m,len;
bool flag[N]; 
int lowbit(int i)
{
    return i&(-i);
}
void init()
{
     int i;
     reph(i,1,n)
     sum[i]=lowbit(i);
 }

void addpage(int x,int y)
{
     a[len].y=y;
     a[len].pre=pre[x];
     pre[x]=len++;
     }
void dfs(int i)//代表的是父亲的节点的下标的 
{ 
     b[i].low=len;//记录开始的时候的 
     int j;
     for(j=pre[i];j!=0; j=a[j].pre)
     {
           dfs(a[j].y);
     }
     b[i].high=len++;//记录结束的结点的  
 }

void update(int i)
{
     int x;
     if(flag[i]==true)
     {
                        x=-1;
                        flag[i]=false;
                        }
     else
     {
         x=1;
         flag[i]=true;
     }
     for(;i<=n; i+=lowbit(i))
     sum[i]+=x;
 }
int Sum(int i)
{
    int m=0;
    for(;i>0;i-=lowbit(i)) 
    m+=sum[i];  
return m;
}
int main()
{
    int x,y,m,i;
    while(scanf("%d",&n)!=EOF)
    {
           len=1;
           memset(pre,0,sizeof(pre));
           memset(sum,0,sizeof(sum)); 
           memset(flag,true,sizeof(flag));//代表树是空或者有苹果的 
           rep(i,n-1)
           {
                scanf("%d%d",&x,&y);  
                addpage(x,y);   //存储的    
           }
           len=1;//用来标记的 
           dfs(1);//进行建立位置的 
           init();//对sum进行操作的 
           scanf("%d",&m);
           char c;
           int s; 
           while(m--)
           {
                    getchar();
                     c=getchar();
                     scanf("%d",&s);
                     if(c=='Q')
                     {   
                         //      printf("%d %d\n",b[s].high,b[s].low);
                               printf("%d\n",Sum(b[s].high)-Sum(b[s].low-1));
                     }
                     else
                     { 
                         update(b[s].high);//开始的结点的 
                     }
           }
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡定的小Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值