hdu2688 Rotate (树状数组)

#include <stdio.h>  
#include <string.h>  
#define MAX 3000002

int arr[10002],a[MAX];  
//树状数组  
int lowBit(int x)
{  
	return (x&(-x));  
}  

void add(int index,int val)
{  
	while(index<10001)  
	{  
		arr[index]+=val;  
		index+=lowBit(index);  
	}  
}  

int get(int num)  
{  
	int sum=0;  
	while(num>0)  
	{  
		sum+=arr[num];  
		num-=lowBit(num); 
	}  
	return sum;  
}  

int main()  
{  
	int n,m,i,x,y,temp;
	char ch;
	while(scanf("%d",&n)!=EOF)  
	{  
		_int64 ans=0;
		memset(arr,0,sizeof(arr));
		memset(a,0,sizeof(a));
		for (i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			add(a[i],1);
			ans+=get(a[i]-1);//a[i]前面比a[i]小的数的和
		}
		scanf("%d",&m);
		while(m--)
		{
			getchar();
			scanf("%c",&ch);
			if(ch=='Q')
				printf("%I64d\n",ans);
			else
			{
				scanf("%d %d",&x,&y);
				x++;//树状数组下标从1开始
				y++;
				temp=a[x];
				for(i=x;i<y;i++)
				{
					a[i]=a[i+1];
					if(a[i]>temp)
						ans--;
					else if(a[i]<temp)
						ans++;
				}
				a[y]=temp;
			}
		}
	}  
	return 0;  
}  





#include <stdio.h>    
#include <string.h>    
#define MAX 3000002  
  
int arr[10002],a[MAX];    

int Scan()// 该外挂适合纯数字输入  
{    
    int res = 0, ch, flag = 0;    
    if((ch = getchar()) == '-')             //判断正负    
        flag = 1;    
    else if(ch >= '0' && ch <= '9')           //得到完整的数    
        res = ch - '0';    
    while((ch = getchar()) >= '0' && ch <= '9' )    
        res = res * 10 + ch - '0';    
    return flag ? -res : res;    
}    

int lowBit(int x)  
{    
    return (x&(-x));    
}    
  
void add(int index,int val)  
{    
    while(index<10001)    
    {    
        arr[index]+=val;    
        index+=lowBit(index);    
    }    
}    
  
int get(int num)    
{    
    int sum=0;    
    while(num>0)    
    {    
        sum+=arr[num];    
        num-=lowBit(num);   
    }    
    return sum;    
}    
  
int main()    
{    
    int n,m,i,x,y,temp;  
    char ch;  
    while(scanf("%d",&n)!=EOF)    
    {    
        _int64 ans=0;  
        memset(arr,0,sizeof(arr));  
        for (i=1;i<=n;i++)  
        {    
	    a[i]=Scan();
            add(a[i],1);  
            ans+=get(a[i]-1);//a[i]前面比a[i]小的数的和  
        }  
        scanf("%d",&m);  
        while(m--)  
        {  
            getchar();  
	    ch=getchar();
            if(ch=='Q')  
                printf("%I64d\n",ans);  
            else  
            {  
                scanf("%d %d",&x,&y);
                x++;//树状数组下标从1开始  
                y++;  
                temp=a[x];  
                for(i=x;i<y;i++)  
                {  
                    a[i]=a[i+1];  
                    if(a[i]>temp)  
                        ans--;  
                    else if(a[i]<temp)  
                        ans++;  
                }  
                a[y]=temp;  
            }  
        }  
    }    
    return 0;    
}    


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值