2024杭电多校4L 寻找宝藏

 

设$f_i$表示从左上角到i节点的最多金币数,$g_i$表示从i节点到右下角的最多金币数(即最大加权不下降子序列)

一个矩阵限制了一定区间不能走,同时也规定了只能通过如下四种方法走过来

 

蓝色表示障碍矩阵,要么在绿色矩阵中选择一个节点x,经过绿色区域一定会避开蓝色矩阵

要么从上方的红色区间选择一个点,然后从右方的红色区间选择一个点,这样也可以避开蓝色矩阵

同理

 

 

选择从下方过来如上,依旧有两种情况

先用树状数组求出$f_i,g_i$,然后再用树状数组求出前缀区间或者后缀区间最大值即可

CODE:

 

 1 #include<bits/stdc++.h>
 2 #define rep(i,a,b) for(int i=a;i<=b;i++)
 3 #define dwn(i,a,b) for(int i=a;i>=b;i--)
 4 #define lowbit(x) (x&(-x))
 5 #define MAXN 302501
 6 #define int long long
 7 using namespace std;
 8 typedef long long ll;
 9 inline int read(){
10     int x=0,f=1;
11     char ch=getchar();
12     while(ch>'9' || ch<'0'){if(ch=='-') f=-1; ch=getchar();}
13     while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
14     return x*f;
15 }
16 int n,m;
17 struct node{
18     int u, ur, r, d, l, dl;
19 }t[MAXN];
20 int p[MAXN],v[MAXN],c[MAXN],N;
21 int f[MAXN],g[MAXN],h[MAXN],ans[MAXN];
22 struct e{
23     int yl, yr;
24 }q[MAXN];
25 vector<int> ql[MAXN],qr[MAXN];
26 void clr(){
27     rep(i,1,n) ql[i].clear(), qr[i].clear();
28 }
29 int get(int x){
30     return n - x + 1;
31 }
32 void ins(int x,int y){
33     while(x <= n) c[x] = max(c[x], y), x += lowbit(x);
34 }
35 int qry(int x){
36     int res = 0;
37     while(x) res = max(res, c[x]), x -= lowbit(x);
38     return res; 
39 }
40 void wk(){
41     n = read(); m = read();
42     rep(i,1,n) p[i] = read(),v[i] = read();
43     rep(i,1,m){
44         int xl,xr;
45         xl = read(); q[i].yl = read();
46         xr = read(); q[i].yr = read();
47         ql[xl].emplace_back(i); qr[xr].emplace_back(i);
48     }
49     rep(i,0,n) c[i] = 0;
50     rep(i,1,n){
51         for(auto j : ql[i]) t[j].l = qry(q[j].yr);
52         f[i] = qry(p[i]) + v[i];
53         ins(p[i],f[i]);
54         for(auto j : qr[i]) t[j].u = qry(q[j].yl - 1);
55     }
56     rep(i,0,n) c[i] = 0;
57     dwn(i,n,1){
58         for(auto j : qr[i]) t[j].r = qry(get(q[j].yl));
59         g[i] = qry(get(p[i])) + v[i];
60         ins(get(p[i]),g[i]);
61         for(auto j : ql[i]) t[j].d = qry(get(q[j].yr + 1));
62     }
63     rep(i,1,n) h[i] = g[i] + f[i] - v[i];
64     rep(i,0,n) c[i] = 0;
65     rep(i,1,n){
66         for(auto j : ql[i]) t[j].dl = qry(get(q[j].yr + 1));
67         ins(get(p[i]),h[i]);
68     }
69     rep(i,0,n) c[i] = 0;
70     dwn(i,n,1){
71         for(auto j : qr[i]) t[j].ur = qry(q[j].yl - 1);
72         ins(p[i],h[i]);
73     }
74     rep(j,1,m) ans[j] = max(max(t[j].dl, t[j].d + t[j].l), max(t[j].ur, t[j].u + t[j].r));
75     rep(i,1,m) printf("%lld\n",ans[i]);
76 }
77 signed main(){
78     int T = read();
79     while(T--){
80         clr();
81         wk();
82     }
83     return 0;
84 }

 

posted @ 2024-07-30 22:54  niolle  阅读(21)  评论(0编辑  收藏  举报