36分 分块做法求助
  • 板块P4891 序列
  • 楼主2018LZY
  • 当前回复4
  • 已保存回复4
  • 发布时间2020/5/14 21:23
  • 上次更新2023/11/7 02:27:31
查看原帖
36分 分块做法求助
118826
2018LZY楼主2020/5/14 21:23
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define gc getchar()
#define ll long long
#define pos(x) ((x-1)/sz+1) 
using namespace std;
const int N=1e5+10,sz=320,T=sz+55,mod=1e9+7;

void qr(int &x) {
	char c=gc; x=0;
	while(!isdigit(c))c=gc;
	while(isdigit(c))x=x*10+c-'0',c=gc;
}
void qw(ll x) {
	if(x/10) qw(x/10);
	putchar(x%10+'0');
}
void pr2(ll x){qw(x); puts("");}

int n,m,t,a[N],b[N],L[T],R[T];
ll ans,P[T];

struct B {
	int L,R,tag,it,len,c[T],mx;
	ll ans,pre[T];
	struct rec {
		int v,id;
		bool operator <(rec b) const {return v<b.v;}
	}B[T];
	void bt(int l,int r) {
		L=l; R=r; len=r-l+1;
		ans=pre[0]=it=1; tag=-1; mx=a[r];
		for(int i=l,j=1;i<=r;i++,j++) c[j]=a[i],B[j]=(rec){b[i],i},ans=ans*min(b[i],a[i])%mod;
		sort(B+1,B+len+1);
		for(int i=1;i<=len;i++) pre[i]=pre[i-1]*B[i].v%mod;
	}
	void lazy() {if(~tag) {for(int i=1;i<=len;i++) c[i]=tag; it=1; tag=-1;}}
	void change_b(int x) {
		lazy();
		int pos=0;
		for(int i=1;i<=len&&!pos;i++) if(B[i].id==x) pos=i;
		B[pos].v=b[x];
		for(int i=pos+1;i<=len;i++) if(B[i-1].v>B[i].v) swap(B[i-1],B[i]); else break;
		ans=1;
		for(int i=1;i<=len;i++) ans=ans*min(B[i].v,c[B[i].id-L+1])%mod,pre[i]=pre[i-1]*B[i].v%mod;
	}
	void change(int l,int r,int x) {
		lazy(); l-=L-1; r-=L-1;
		for(int i=l;i<=r;i++) c[i]=x;
		ans=1; mx=c[len];
		for(int i=1;i<=len;i++) ans=ans*min(B[i].v,c[B[i].id-L+1])%mod;
	}
	void all(int x) {
		tag=mx=x;
		while(it<=len&&B[it].v<x) it++;
		ans=pre[it-1]*P[len-it+1]%mod;
	}
	int& operator [](int x) {return ~tag?tag:c[x-L+1];}
}g[T];

int main() {
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	qr(n); qr(m); t=pos(n);
	for(int i=1;i<=n;i++) qr(a[i]),a[i]=max(a[i],a[i-1]);
	for(int i=1;i<=n;i++) qr(b[i]);
	for(int i=1;i<=t;i++) L[i]=R[i-1]+1,R[i]=i*sz; 		R[t]=n;
	for(int i=1;i<=t;i++) g[i].bt(L[i],R[i]);
	int op,x,y,p,q,r;
	while(m--) {
		qr(op); qr(x); qr(y); p=pos(x);
		if(op) {
			if(b[x]^y) b[x]=y,g[p].change_b(x);
		}
		else if(g[p][x]<y) {
			q=t; r=n;
			for(int i=p;i<=t;i++) if(g[i].mx>=y)
				for(int j=L[i];j<=R[i];j++) if(g[i][j]>=y) {q=i; r=j-1; break;}
			if(p==q) g[p].change(x,r,y);
			else {
				g[p].change(x,R[p],y);
				if(p+1<q) {
					P[0]=1;for(int i=1;i<=sz;i++) P[i]=P[i-1]*y%mod;
					for(int i=p+1;i<q;i++) g[i].all(y);
				}
				g[q].change(L[q],r,y);
			}
		}
		ans=1;
		for(int i=1;i<=t;i++) ans=ans*g[i].ans%mod;
		pr2(ans);
	}
	return 0;
}

2020/5/14 21:23
加载中...