6月21日 bc总结

6月21日 bc总结

最近bc由于急于提交,增加了WA的概率,今天1001数据没测完全就提交了,WA了一次,很不划算,在bc等于罚时10min,下次一定要确保数据正确且所有的情况都考虑到再提交。

1001

水题,5分钟WA了一次,6分钟过。手速还是慢了,重点是居然WA了一次。

1002

给定一个数组,多次询问L和R区间内的逆序数。

数组大小是小于1000。

暴力FST了。

思路:设dp(l,r)为区间 l 到 r 的逆序数。dp(l,r)=dp(l,r-1)+cnt(l,r),其中cnt(l,r)表示a[r]对dp(l,r)的贡献,即区间 [l,r-1] 中比a[r]大的数的个数。

求出cnt,之后直接n^2预处理即可求出dp(l,r)。

现在问题在怎么求cnt(l,r)。

对简单的方法是直接n^3暴力,显然是不行的。

可以这样考虑,对区间[l,r],a[r]对该区间的贡献为cnt(l,r),即[l,r-1]中比a[r]大的数的个数,而cnt(l+1,r)表示[l+1,r-1]中比a[r]大的数的个数,而cnt(l+1,r)和cnt(l,r)之间差了什么,没错,差的就是(a[l],a[r])这对逆序数。

因此,cnt(l,r)=cnt(l+1,r)+(a[l]>a[r]) .   n^2预处理即可,由于cnt(l+1,r)比cnt(l,r)先被算出来,所以要反着推。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<math.h>
#include<cctype>
#define ll long long
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))
#define rep(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define repp(i,a,b,t) for(int (i)=(a);(i)>=(b);(i)-=(t))
#define PII pair<int,int>
#define fst first
#define snd second
#define MP make_pair
#define PB push_back
#define RI(x) scanf("%d",&(x))
#define RII(x,y) scanf("%d%d",&(x),&(y))
#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define DRI(x) int (x);scanf("%d",&(x))
#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d",&(x),&(y),&(z))
#define RS(x) scanf("%s",s)
#define RSS(x,y) scanf("%s%s",x,y)
#define DRS(x) char x[maxn];scanf("%s",x)
#define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y)
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),-1,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))
#define ALL(v) v.begin(),v.end()
#define SZ(v) (v).size()

using namespace std;

const int maxn=1100;
const int INF=(1<<29);
const double EPS=0.0000000001;
const double Pi=acos(-1.0);

int n,q;
int a[maxn];
int f[maxn][maxn],cnt[maxn][maxn];

int main()
{
    while(cin>>n>>q){
        MS0(f);
        MS0(cnt);
        REP(i,1,n) RI(a[i]);
        rep(i,n,1){
            rep(j,n,i){
                cnt[i][j]=cnt[i+1][j]+(a[i]>a[j]);
            }
        }
        REP(i,1,n){
            REP(j,i,n){
                f[i][j]=f[i][j-1]+cnt[i][j];
            }
        }
        while(q--){
            DRII(l,r);
            printf("%d\n",f[l][r]);
        }
    }
    return 0;
}
View Code

 这题用树状数组也可以,数据结构的优势就是减少思维量,增加做题的稳定性,今晚rank前几名的很多人都是秒写树状数组过的。看来树状数组是个很有用的工具,一定要好好学。

posted @ 2015-06-21 01:00  __560  阅读(223)  评论(0编辑  收藏  举报