noi.ac 111 运气大战

#111. 运气大战

 

 

由于排序不等式,我们尽量想顺序放。两边都排序。

由于 n 个不能配的干扰,又不能完全顺序放。

有个结论,最后匹配出第 i 个人的运气值是第 j 个的话,|i-j|\le2ij2。这个结论从最小化逆序对的个数来看,自己把附近几个线连起来画一画证明一下。

这样就可以用 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 }

 

posted @ 2018-11-06 16:31  zjxxcn  阅读(230)  评论(0编辑  收藏  举报