你说得对,但是我悬赏4关

P8818 [CSP-S 2022] 策略游戏

~~如果你用线段树我应该会帮你~~ ~~还有你的压行~~
by FuncoF9 @ 2023-08-04 17:16:28


@[aaaadou](https://www.luogu.com.cn/user/550935) 那你帮我看看行吗
by lsx1234 @ 2023-08-04 17:17:54


@[aaaadou](https://www.luogu.com.cn/user/550935) ``` #include<bits/stdc++.h> #define ll long long using namespace std; int n,m,q,a[100005],b[100005]; struct node{ int max_positive,max_negative,minp,minn; }treea[100005],treeb[100005]; node ask(int x,int lx,int rx,int l,int r,node tree[]){ if(lx>=l && rx<=r){ return tree[x]; } int mid=(lx+rx)>>1; if(r<=mid){ return ask(x<<1,lx,mid,l,r,tree); } if(l>=mid){ return ask(x<<1+1,mid+1,rx,l,r,tree); } node tmpl=ask(x<<1,lx,mid,l,r,tree); node tmpr=ask(x<<1|1,mid+1,rx,l,r,tree); node tmp; tmp.max_positive=max(tmpl.max_positive,tmpr.max_positive); if(tmpl.max_negative>=0){ tmp.max_negative=tmpr.max_negative; }else if(tmpr.max_negative>=0){ tmp.max_negative=tmpl.max_negative; }else{ tmp.max_negative=max(tmpl.max_negative,tmpr.max_negative); } if(tmpl.minp<0){ tmp.minp=tmpr.minp; } else if(tmpr.minp<0){ tmp.minp=tmpl.minp; } else{ tmp.minp=min(tmpl.minp,tmpr.minp); } tmp.minn=min(tmpl.minn,tmpr.minn); return tmp; } void push(int x,node tree[]){ tree[x].max_positive=max(tree[x<<1].max_positive,tree[x<<1|1].max_positive); if(tree[x<<1].max_positive>=0){ tree[x].max_negative=tree[x<<1|1].max_negative; }else if(tree[x<<1+1].max_negative>=0){ tree[x].max_negative=tree[x<<1].max_negative; }else{ tree[x].max_negative=max(tree[x<<1].max_negative,tree[x<<1|1].max_negative); } if(tree[x<<1].minp<0){ tree[x].minp=tree[x<<1|1].minp; }else if(tree[x<<1|1].minp<0){ tree[x].minp=tree[x<<1].minp; }else{ tree[x].minp=min(tree[x<<1].minp,tree[x<<1|1].minp); } tree[x].minn=min(tree[x<<1].minn,tree[x<<1|1].minn); } void build(int x,int l,int r,int c[],node tree[]){//建树 if(l==r){ if(c[l]>=0){ tree[x].max_positive=tree[x].minn=c[l]; } else{ tree[x].max_negative=tree[x].minn=c[l]; tree[x].max_positive=tree[x].minp=-1; } } else{ int mid=(l+r)>>1; build(x<<1,l,mid,c,tree); build(x<<1|1,mid+1,r,c,tree); push(x,tree); } return ; } int main(){ cin>>n>>m>>q; for(int i=1;i<=n;++i){ cin>>a[i]; } for(int i=1;i<=m;++i){ cin>>b[i]; } build(1,1,n,a,treea); build(1,1,m,b,treeb); for(int i=1;i<=q;++i){ int l1,r1,l2,r2,ans; cin>>l1>>r1>>l2>>r2; node tmpa=ask(1,1,n,l1,r1,treea); int mpa=tmpa.max_positive,mna=tmpa.max_negative,ipa=tmpa.minp,ina=tmpa.minn; node tmpb=ask(1,1,m,l1,r1,treeb); int mpb=tmpb.max_positive,mnb=tmpb.max_negative,ipb=tmpb.minp,inb=tmpb.minn; int sua=0,sub=0; if(inb>=0) { if(mpa>=0){ sua=mpa; } else{ sua=mna; } } else{ if(mnb<0){ if(ina<0){ sua=ina; } else{ sua=ipa; } } else{ if(mpa<0){ sua=mna; } else if(mna>=0){ sua=mpa; } else if(inb*ipa>mnb*mna){ sua=ina; } else{ sua=mna; } } } if(sua>=0){ if(inb<0){ sub=inb; } else{ sub=inb; } } else{ if(mnb>=0){ sub=mnb; } else{ sub=mnb; } } cout<<sua*sub<<endl; } return 0; } ```
by lsx1234 @ 2023-08-04 17:18:41


![](//图.tk/1)
by ACPC @ 2023-08-04 17:19:04


这么强,都用线段树![](//图.tk/1)![](//图.tk/1)
by ACPC @ 2023-08-04 17:20:12


@[A_Passing_Creeper](/user/540363) ## Code: ``` #include<bits/stdc++.h> using namespace std; typedef long long ll; inline int read(){ char ch=getchar();int x=0, f=1; while(!isdigit(ch)) f=(ch=='-')?-1:f, ch=getchar(); while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0', ch=getchar(); return x*f; } const int N=1e5+5; int n, m, q, p[2][N]; #define ls k<<1 #define rs k<<1|1 #define mid (l+r>>1) struct node{ int Mxz, Mnz; int Mxf, Mnf; int type(){ if(Mxf==0&&Mnf==0) return 1; if(Mxz==0&&Mnz==0) return 3; return 2; } void print(){ printf("type %d : +(%d %d), -(%d %d)\n", type(), Mxz, Mnz, Mxf, Mnf); } }tr[2][N*4]; node init(int x){return (node){max(0, x), max(0, x), min(0, x), min(0, x)};} int MN(int x, int y){ if(!x&&!y) return 0; if(x&&y) return min(x, y); return x?x:y; } int MX(int x, int y){ if(!x&&!y) return 0; if(x&&y) return max(x, y); return x?x:y; } node operator + (node L, node R){ node res; res.Mxz=max(L.Mxz, R.Mxz); res.Mnz=MN(L.Mnz, R.Mnz); res.Mxf=MX(L.Mxf, R.Mxf); res.Mnf=min(L.Mnf, R.Mnf); return res; } void build(int k, int l, int r, int op){ if(l==r) return (void)(tr[op][k]=init(p[op][l&r])); build(ls, l, mid, op), build(rs, mid+1, r, op); tr[op][k]=tr[op][ls]+tr[op][rs]; // printf("for tr[%d] range [%d %d]\n", op, l, r);tr[op][k].print(); } node query(int k, int l, int r, int x, int y, int op){ if(x>r||y<l) return init(0); if(x<=l&&r<=y) return tr[op][k]; return query(ls, l, mid, x, y, op)+query(rs, mid+1, r, x, y, op); } #undef ls #undef rs #undef mid #define lowbit(x) ((x)&(-x)) int bit[2][N]; void add(int x, int up, int op, int v){for(; x<=up; x+=lowbit(x)) bit[op][x]+=v;} int query(int x, int op){int res=0;for(; x; x-=lowbit(x)) res+=bit[op][x];return res;} #undef lowbit signed main(){ n=read(), m=read(), q=read(); for(int i=1; i<=n; ++i) p[0][i]=read(), add(i, n, 0, (p[0][i]==0)); for(int i=1; i<=m; ++i) p[1][i]=read(), add(i, n, 1, (p[1][i]==0)); build(1, 1, n, 0), build(1, 1, m, 1); for(int i=1; i<=q; ++i){ int l_1=read(), r_1=read(), l_2=read(), r_2=read(); node A=query(1, 1, n, l_1, r_1, 0); node B=query(1, 1, m, l_2, r_2, 1); ll ans;//A.print(), B.print(); if(A.type()==1){ if(B.type()==1) ans=1ll*A.Mxz*B.Mnz; if(B.type()==2) ans=1ll*A.Mnz*B.Mnf; if(B.type()==3) ans=1ll*A.Mnz*B.Mnf; } if(A.type()==2){ if(B.type()==1) ans=1ll*A.Mxz*B.Mnz; if(B.type()==2) ans=max(1ll*A.Mnz*B.Mnf, 1ll*A.Mxf*B.Mxz); if(B.type()==3) ans=1ll*A.Mnf*B.Mxf; } if(A.type()==3){ if(B.type()==1) ans=1ll*A.Mxf*B.Mxz; if(B.type()==2) ans=1ll*A.Mxf*B.Mxz; if(B.type()==3) ans=1ll*A.Mnf*B.Mxf; } if(query(r_1, 0)-query(l_1-1, 0)) ans=max(ans, 0ll); if(query(r_2, 1)-query(l_2-1, 1)) ans=min(ans, 0ll); printf("%lld\n", ans); } return 0; } ```
by 2012GFKKKZ @ 2023-08-04 17:22:59


@[fendigao](/user/1037866) 可是我不想要线段树啊![](//图.tk/1)![](//图.tk/1)
by ACPC @ 2023-08-04 17:23:56


不如这个: ```cpp #include<bits/stdc++.h> using namespace std; typedef long long ll; const ll maxlogn=17,maxn=100000,SIZE[20]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,37268,65536,131072,262144,524288},maxq=100000; const double ERR=1e-7; ll st[11][maxlogn+5][maxn+5]; ll n,m,a[maxn+9],b[maxn+9],top1,top2,q,left1[maxq+1],right1[maxq+1],left2[maxq+1],right2[maxq+1]; string SSSS[9]={"","amax","bmax","amin","bmin","+amin","+bmin","-amax","-bmax"}; void first(){ for(int i=1;i<=n;i++) st[1][1][i]=a[i]; for(int i=2;i<=top1;i++) for(int j=1;j<=n-SIZE[i-1]+1;j++) st[1][i][j]=max(st[1][i-1][j],st[1][i-1][j+SIZE[i-2]]); } void second(){ for(int i=1;i<=m;i++) st[2][1][i]=b[i]; for(int i=2;i<=top2;i++) for(int j=1;j<=m-SIZE[i-1]+1;j++) st[2][i][j]=max(st[2][i-1][j],st[2][i-1][j+SIZE[i-2]]); } void third(){ for(int i=1;i<=n;i++) st[3][1][i]=a[i]; for(int i=2;i<=top1;i++) for(int j=1;j<=n-SIZE[i-1]+1;j++) st[3][i][j]=min(st[3][i-1][j],st[3][i-1][j+SIZE[i-2]]); } void fourth(){ for(int i=1;i<=m;i++) st[4][1][i]=b[i]; for(int i=2;i<=top2;i++) for(int j=1;j<=m-SIZE[i-1]+1;j++) st[4][i][j]=min(st[4][i-1][j],st[4][i-1][j+SIZE[i-2]]); } void fifth(){ for(int i=1;i<=n;i++) if(a[i]>=0) st[5][1][i]=a[i]; else st[5][1][i]=3e9; for(int i=2;i<=top1;i++) for(int j=1;j<=n-SIZE[i-1]+1;j++) st[5][i][j]=min(st[5][i-1][j],st[5][i-1][j+SIZE[i-2]]); } void sixth(){ for(int i=1;i<=m;i++) if(b[i]>=0) st[6][1][i]=b[i]; else st[6][1][i]=3e9; for(int i=2;i<=top2;i++) for(int j=1;j<=m-SIZE[i-1]+1;j++) st[6][i][j]=min(st[6][i-1][j],st[6][i-1][j+SIZE[i-2]]); } void seventh(){ for(int i=1;i<=n;i++) if(a[i]<=0) st[7][1][i]=a[i]; else st[7][1][i]=-3e9; for(int i=2;i<=top1;i++) for(int j=1;j<=n-SIZE[i-1]+1;j++) st[7][i][j]=max(st[7][i-1][j],st[7][i-1][j+SIZE[i-2]]); } void eighth(){ for(int i=1;i<=m;i++) if(b[i]<=0) st[8][1][i]=b[i]; else st[8][1][i]=-3e9; for(int i=2;i<=top2;i++) for(int j=1;j<=m-SIZE[i-1]+1;j++) st[8][i][j]=max(st[8][i-1][j],st[8][i-1][j+SIZE[i-2]]); } void gettop(){ for(int i=0;i<=19;i++) if(n>=SIZE[i]) top1=i+1; for(int i=0;i<=19;i++) if(m>=SIZE[i]) top2=i+1; } void input(){ cin>>n>>m>>q; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=m;i++) cin>>b[i]; for(int i=1;i<=q;i++) cin>>left1[i]>>right1[i]>>left2[i]>>right2[i]; } bool anoup(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[1][flr][l]<=0; if(l+SIZE[flr-1]-1>r) return anoup(l,r,flr-1); return st[1][flr][l]<=0&&anoup(l+SIZE[flr-1],r,flr-1); } bool anodown(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[3][flr][l]>=0; if(l+SIZE[flr-1]-1>r) return anodown(l,r,flr-1); return st[3][flr][l]>=0&&anodown(l+SIZE[flr-1],r,flr-1); } bool bnoup(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[2][flr][l]<=0; if(l+SIZE[flr-1]-1>r) return bnoup(l,r,flr-1); return st[2][flr][l]<=0&&bnoup(l+SIZE[flr-1],r,flr-1); } bool bnodown(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[4][flr][l]>=0; if(l+SIZE[flr-1]-1>r) return bnodown(l,r,flr-1); return st[4][flr][l]>=0&&bnodown(l+SIZE[flr-1],r,flr-1); } ll amax(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[1][flr][l]; if(l+SIZE[flr-1]-1>r) return amax(l,r,flr-1); return max(st[1][flr][l],amax(l+SIZE[flr-1],r,flr-1)); } ll bmax(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[2][flr][l]; if(l+SIZE[flr-1]-1>r) return bmax(l,r,flr-1); return max(st[2][flr][l],bmax(l+SIZE[flr-1],r,flr-1)); } ll amin(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[3][flr][l]; if(l+SIZE[flr-1]-1>r) return amin(l,r,flr-1); return min(st[3][flr][l],amin(l+SIZE[flr-1],r,flr-1)); } ll bmin(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[4][flr][l]; if(l+SIZE[flr-1]-1>r) return bmin(l,r,flr-1); return min(st[4][flr][l],bmin(l+SIZE[flr-1],r,flr-1)); } ll apmin(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[5][flr][l]; if(l+SIZE[flr-1]-1>r) return apmin(l,r,flr-1); return min(st[5][flr][l],apmin(l+SIZE[flr-1],r,flr-1)); } ll bpmin(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[6][flr][l]; if(l+SIZE[flr-1]-1>r) return bpmin(l,r,flr-1); return min(st[6][flr][l],bpmin(l+SIZE[flr-1],r,flr-1)); } ll admax(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[7][flr][l]; if(l+SIZE[flr-1]-1>r) return admax(l,r,flr-1); return max(st[7][flr][l],admax(l+SIZE[flr-1],r,flr-1)); } ll bdmax(ll l,ll r,ll flr){ if(l+SIZE[flr-1]-1==r) return st[8][flr][l]; if(l+SIZE[flr-1]-1>r) return bdmax(l,r,flr-1); return max(st[8][flr][l],bdmax(l+SIZE[flr-1],r,flr-1)); } void doallup(ll id){ cout<<amax(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bmin(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR))<<endl; } void doalldown(ll id){ cout<<amin(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bmax(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR))<<endl; } void doaupbdown(ll id){ cout<<apmin(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bmin(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR))<<endl; } void doadownbup(ll id){ cout<<admax(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bmax(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR))<<endl; } void doaup(ll id){ cout<<apmin(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bmin(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR))<<endl; } void dobup(ll id){ cout<<amax(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bpmin(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR))<<endl; } void doadown(ll id){ cout<<admax(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bmax(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR))<<endl; } void dobdown(ll id){ cout<<amin(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bdmax(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR))<<endl; } void doallhave(ll id){ ll dd1=apmin(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bmin(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR)); ll dd2=admax(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR))*bmax(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR)); cout<<max(dd1,dd2)<<endl; } void query(ll id){ bool A=anoup(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR)); bool B=bnoup(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR)); bool C=anodown(left1[id],right1[id],floor(log2(right1[id]-left1[id]+1)+1+ERR)); bool D=bnodown(left2[id],right2[id],floor(log2(right2[id]-left2[id]+1)+1+ERR)); if(1){ if(C&&D){ doallup(id); return; } if(A&&B){ doalldown(id); return; } if(A&&D){ doadownbup(id); return; } if(B&&C){ doaupbdown(id); return; } if(A){ doadown(id); return; } if(B){ dobdown(id); return; } if(C){ doaup(id); return; } if(D){ dobup(id); return; } doallhave(id); return; } } int main(){ //freopen("game.in","r",stdin); //freopen("game.out","w",stdout); input(); gettop(); first(); second(); third(); fourth(); fifth(); sixth(); seventh(); eighth(); for(int i=1;i<=q;i++) query(i); return 0; } ```
by fenwicktree @ 2023-08-04 17:24:57


@A_Passing_Creeper可我也没办法呀
by 2012GFKKKZ @ 2023-08-04 17:26:05


@[lsx1234](/user/718658) 你这个代码问题还挺多。。 贪心部分可以自己想想。 把我的代码中线段树的贴一下; ```cpp struct SegmentTree { int l, r; int maxp, maxn, minp, minn; // positive negative int flagz; } ta[N * 4], tb[N * 4]; int a[N], b[N]; void pushupa(int p) { ta[p].maxp = max(ta[p * 2].maxp, ta[p * 2 + 1].maxp); ta[p].minp = min(ta[p * 2].minp, ta[p * 2 + 1].minp); ta[p].maxn = max(ta[p * 2].maxn, ta[p * 2 + 1].maxn); ta[p].minn = min(ta[p * 2].minn, ta[p * 2 + 1].minn); ta[p].flagz = ta[p * 2].flagz || ta[p * 2 + 1].flagz; } void builda(int p, int l, int r) { ta[p].l = l, ta[p].r = r; if (l == r) { if (a[l] > 0) { ta[p].maxp = ta[p].minp = a[l]; ta[p].maxn = -INF; ta[p].minn = INF; ta[p].flagz = 0; } else if (a[l] == 0) { ta[p].maxp = ta[p].maxn = -INF; ta[p].minp = ta[p].minn = INF; ta[p].flagz = 1; } else { ta[p].maxn = ta[p].minn = a[l]; ta[p].maxp = -INF; ta[p].minp = INF; ta[p].flagz = 0; } return; } int mid = (l + r) / 2; builda(p * 2, l, mid); builda(p * 2 + 1, mid + 1, r); pushupa(p); } void pushupb(int p) { tb[p].maxp = max(tb[p * 2].maxp, tb[p * 2 + 1].maxp); tb[p].minp = min(tb[p * 2].minp, tb[p * 2 + 1].minp); tb[p].maxn = max(tb[p * 2].maxn, tb[p * 2 + 1].maxn); tb[p].minn = min(tb[p * 2].minn, tb[p * 2 + 1].minn); tb[p].flagz = tb[p * 2].flagz || tb[p * 2 + 1].flagz; } void buildb(int p, int l, int r) { tb[p].l = l, tb[p].r = r; if (l == r) { if (b[l] > 0) { tb[p].maxp = tb[p].minp = b[l]; tb[p].maxn = -INF; tb[p].minn = INF; tb[p].flagz = 0; } else if (b[l] == 0) { tb[p].maxp = tb[p].maxn = -INF; tb[p].minp = tb[p].minn = INF; tb[p].flagz = 1; } else { tb[p].maxn = tb[p].minn = b[l]; tb[p].maxp = -INF; tb[p].minp = INF; tb[p].flagz = 0; } return; } int mid = (l + r) / 2; buildb(p * 2, l, mid); buildb(p * 2 + 1, mid + 1, r); pushupb(p); } SegmentTree querya(int p, int l, int r) { if (l <= ta[p].l && ta[p].r <= r) { return ta[p]; } int mid = (ta[p].l + ta[p].r) / 2; if (l > mid) return querya(p * 2 + 1, l, r); if (r <= mid) return querya(p * 2, l, r); if (l <= mid && r > mid) { SegmentTree a = querya(p * 2, l, r), b = querya(p * 2 + 1, l, r), res; res.maxp = max(a.maxp, b.maxp); res.minp = min(a.minp, b.minp); res.maxn = max(a.maxn, b.maxn); res.minn = min(a.minn, b.minn); res.flagz = a.flagz || b.flagz; return res; } } SegmentTree queryb(int p, int l, int r) { if (l <= tb[p].l && tb[p].r <= r) { return tb[p]; } int mid = (tb[p].l + tb[p].r) / 2; if (l > mid) return queryb(p * 2 + 1, l, r); if (r <= mid) return queryb(p * 2, l, r); if (l <= mid && r > mid) { SegmentTree a = queryb(p * 2, l, r), b = queryb(p * 2 + 1, l, r), res; res.maxp = max(a.maxp, b.maxp); res.minp = min(a.minp, b.minp); res.maxn = max(a.maxn, b.maxn); res.minn = min(a.minn, b.minn); res.flagz = a.flagz || b.flagz; return res; } } ```
by FuncoF9 @ 2023-08-04 17:26:06


| 下一页