noi.ac 111 运气大战
#111. 运气大战
由于排序不等式,我们尽量想顺序放。两边都排序。
由于 n 个不能配的干扰,又不能完全顺序放。
有个结论,最后匹配出第 i 个人的运气值是第 j 个的话,|i-j|\le2∣i−j∣≤2。这个结论从最小化逆序对的个数来看,自己把附近几个线连起来画一画证明一下。
这样就可以用 dp[i]表示到 i 为止所有配好的最优答案。计算的时候需要用到前三轮的答案然后讨论一下。这个是 O(nq)的,可以过70%。
用线段树记录区间答案。区间记录这样的信息:把这个区间前0-2个和后0-2个元素去掉的答案,用3x3的矩阵维护。这样复杂度是O(qlogn)。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i=a;i<=b;i++) 4 #define Rep(i,a,b) for(int i=a;i>=b;i--) 5 #define ms(i,a) memset(a,i,sizeof(a)) 6 #define LL long long 7 #define A first 8 #define B second 9 #define pii pair<long long ,long long > 10 #define mp make_pair 11 #define mid (l+r)/2 12 #define lc (o<<1) 13 #define rc (o<<1|1) 14 template<class T>void read(T &x){ 15 x=0;char c=0; 16 while (!isdigit(c)) c=getchar(); 17 while (isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar(); 18 } 19 template<class T>void write(T x){ 20 if(x>9) write(x/10); 21 putchar(48+x%10); 22 } 23 template<class T>void chkmax(T &x,T y){x=max(x,y);} 24 int const maxn=30003; 25 pii w[maxn],r[maxn]; 26 int pw[maxn],pr[maxn],n,q; 27 struct node{ 28 LL c[3][3]; 29 node(){ms(-63,c);} 30 node operator ^(const node &t)const{ 31 node x; rep(i,0,2)rep(j,0,2)rep(k,0,2) x.c[i][j]=max(x.c[i][j],c[i][k]+t.c[k][j]); return x; 32 } 33 void init(int x){ 34 ms(-63,c); 35 if(w[x].B!=r[x].B) c[0][0]=w[x].A*r[x].A; 36 if(x>1) c[1][0]=w[x].A*r[x-1].A+w[x-1].A*r[x].A; 37 if(x>2){ 38 c[2][0]=w[x].A*r[x-1].A+w[x-1].A*r[x-2].A+w[x-2].A*r[x].A; 39 chkmax(c[2][0],w[x].A*r[x-2].A+w[x-2].A*r[x-1].A+w[x-1].A*r[x].A); 40 } 41 c[0][1]=0; 42 c[1][2]=0; 43 } 44 }; 45 struct seg{ 46 node t[maxn<<2]; 47 void build(int o,int l,int r){ 48 if(l==r) { t[o].init(l); return; }; 49 build(lc,l,mid); build(rc,mid+1,r); 50 t[o]=t[lc]^t[rc]; 51 } 52 void update(int o,int l,int r,int x){ 53 if(l==r) {t[o].init(l);return;}; 54 if(x<=mid) update(lc,l,mid,x); else update(rc,mid+1,r,x); 55 t[o]=t[lc]^t[rc]; 56 } 57 }T; 58 int main(){ 59 read(n); 60 read(q); 61 rep(i,1,n) read(w[i].A),w[i].B=i; 62 rep(i,1,n) read(r[i].A),r[i].B=i; 63 sort(w+1,w+n+1); 64 sort(r+1,r+n+1); 65 rep(i,1,n) pw[w[i].B]=i; 66 rep(i,1,n) pr[r[i].B]=i; 67 T.build(1,1,n); 68 while (q--){ 69 int x,y; read(x); read(y); 70 swap(r[pr[x]].B,r[pr[y]].B); 71 swap(pr[x],pr[y]); 72 T.update(1,1,n,pr[x]); 73 T.update(1,1,n,pr[y]); 74 write(T.t[1].c[0][0]); putchar('\n'); 75 } 76 return 0; 77 }