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