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前几名的很多人都是秒写树状数组过的。看来树状数组是个很有用的工具,一定要好好学。

你可能感兴趣的:(总结)