hdu 5.3.6 2688 rotate

把对妹子的烦躁,转移到码代码的身上,你妹谁知道它又转回来了。

Rotate

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 77 Accepted Submission(s): 17
 
Problem Description
Recently yifenfei face such a problem that give you millions of positive integers,tell how many pairs i and j that satisfy F[i] smaller than F[j] strictly when i is smaller than j strictly. i and j is the serial number in the interger sequence. Of course, the problem is not over, the initial interger sequence will change all the time. Changing format is like this [S E] (abs(E-S)<=1000) that mean between the S and E of the sequece will Rotate one times.
For example initial sequence is 1 2 3 4 5.
If changing format is [1 3], than the sequence will be 1 3 4 2 5 because the first sequence is base from 0.
 
Input
The input contains multiple test cases.
Each case first given a integer n standing the length of integer sequence (2<=n<=3000000) 
Second a line with n integers standing F[i](0<F[i]<=10000)
Third a line with one integer m (m < 10000)
Than m lines quiry, first give the type of quiry. A character C, if C is ‘R’ than give the changing format, if C equal to ‘Q’, just put the numbers of satisfy pairs.
 
Output
Output just according to said.
 
Sample Input
5
1 2 3 4 5
3
Q
R 1 3
Q
 
Sample Output
10
8
 

标题要不要这么对应我的心情啊混蛋!

这题被坑了。看不懂树状数组的神奇用法就算了,居然还要开外挂才过。而且外挂要开三处……到底是有多少输入啊混蛋!难怪连建议用scanf都不写了,因为用scanf都没用啊泪!

#include <iostream>
#define maxn 10002
#define l __int64
using namespace std;



int n;
int c[maxn];
int ans[3000003];

int lowbit(int x)
{    return -x&x;   }



void add(int pos) 
{
     while(pos<maxn)
     {
         c[pos]++;
         pos+=lowbit(pos);
     }
} 
l sum(int pos)
{
    l s=0;
    while(pos>0)
    {
        s+=c[pos];
        pos-=lowbit(pos);
    }
    return s;
}


bool scan_ud(int &num) { // 传说中的外挂  
    char in;  
    in = getchar();  
   /* if (in == EOF)  
        return false;  */
    while (in < '0' || in > '9')  //leading spaces?
        in = getchar();  
    num = in - '0';  
    while (in = getchar(), in >= '0' && in <= '9') {  
        num *= 10, num += in - '0';  
    }  
    return true;  
}  


int main()
{
    int i;
    int m;
    while(scanf("%d",&n)!=EOF)
    {
        memset(c,0,sizeof(c));
        l val=0;
        for(i=0;i<n;i++)
        {
             //scanf("%d",&ans[i]);
             scan_ud(ans[i]);
             add(ans[i]);
             val+=sum(ans[i]-1);
             //c[i] save the number small or equal to i in i's branch
             //val need to plus what is smaller(cant equal!)
             //so,-1
             
        }
        scanf("%d",&m);
        while(m--)
        {
             char str[3];
             scanf("%s",str);
             if(str[0]=='Q')
             {
                 printf("%I64d\n",val);
             }
             else
             {
                 int s,e;
                 //scanf("%d%d",&s,&e);
                 scan_ud(s);
                 scan_ud(e);
                 if(s>e)
                 {
                     s=s^e;
                     e=s^e;
                     s=s^e;
                 }
                 if(s!=e)
                 {
                     int v=ans[s];
                     int t1=0,t2=0;
                     for(i=s;i<e;i++)
                     {
                         ans[i]=ans[i+1];//rotate
                         if(v<ans[i+1])
                         {
                             t1++;
                         }
                         if(v>ans[i+1])
                             t2++;
                     }
                     ans[e]=v;
                     val=val-t1+t2;
                 }
             }
        }
    }
    return 0;
}
                         
                 

注意:

1.val要用long long(__int64)存,输出用%I64d。

2.首先将N个数的顺序数用树状数组求出来。就是每输入一个树就查询之前比他小的保存。然后添加这个数。

3.然后对于每次R操作,统计在[S+1,E]区间中比v[S]大的数和小的数的个数,将之前的顺序数 - 比它大的数 + 比它小的数,更新这个值。具体可手推一下,就是原来在第一个数后面比他大的(构成顺序对的)现在移到它前面不构成顺序对了,所以减掉。小的同理。

4.外挂。

bool scan_ud(int &num) { // 传说中的外挂  
    char in;  
    in = getchar();  
   /* if (in == EOF)  
        return false;  */
    while (in < '0' || in > '9')  //leading spaces?
        in = getchar();  
    num = in - '0';  
    while (in = getchar(), in >= '0' && in <= '9') {  
        num *= 10, num += in - '0';  
    }  
    return true;  
}  
相当于自己写一个int输入。就是读字符乘十累加。注意前导空格(?)的消去。因为我们知道一定会有读入的所以in==EOF可忽视,其实用void也可以吧……

that's all~

好像抽人啊抽人啊抽人啊混蛋!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值