【计蒜客】贝壳找房户外拓展(中等)扫描线+线段树

【题目】贝壳找房户外拓展(中等)
【题意】给定(n imes m)的棋盘,q次操作:1.在一个列区间设置p和q。2.询问一个行区间,初始x为0,从左到右x=x*p+q,求x。3.撤销一次设置操作。保证所有1和3都在2前面。(n,m,q leq 10^5)
【算法】扫描线+线段树
【题解】离线x维进行扫描线,每次列区间的设置在上端+1,下端+1处-1,这样就转化为序列上的单点插入和区间查询。
考虑线段树维护两个值P和Q,每次合并(P=P_1*P_2,Q=Q_1*P_2+Q_2)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define ll long long
#define lowbit(x) x&-x
using namespace std;
bool isdigit(char c){return c>='0'&&c<='9';}
int read(){
    char c;int s=0,t=1;
    while(!isdigit(c=getchar()))if(c=='-')t=-1;
    do{s=s*10+c-'0';}while(isdigit(c=getchar()));
    return s*t;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a<b?b:a;}
int ab(int x){return x>0?x:-x;}
//int MO(int x){return x>=MOD?x-MOD:x;}
//void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,MOD=323232323,maxn=100010;

int n,m,tot=0,cnt=0,ANS[maxn];
bool vis[maxn];
char s[10];
struct A{
	int x,l,r,id;
	bool operator < (const A &a)const{
		return x<a.x;
	}
}a[maxn];
struct B{
	int x,y,p,q,kind;
	bool operator < (const B &a)const{
		return x<a.x;
	}
}b[maxn*2];
struct tree{int l,r,p,q;}t[maxn*4];
void up(int k){
	t[k].p=1ll*t[k<<1].p*t[k<<1|1].p%MOD;
	t[k].q=(1ll*t[k<<1].q*t[k<<1|1].p+t[k<<1|1].q)%MOD;
}
void build(int k,int l,int r){
	t[k].l=l;t[k].r=r;t[k].p=1;t[k].q=0;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}
void insert(int k,int x,int p,int q){
	if(t[k].l==t[k].r){t[k].p=p;t[k].q=q;return;}
	int mid=(t[k].l+t[k].r)>>1;
	if(x<=mid)insert(k<<1,x,p,q);
	else insert(k<<1|1,x,p,q);
	up(k);
}
int P,Q;
void query(int k,int l,int r){
	if(l<=t[k].l&&t[k].r<=r){P=1ll*P*t[k].p%MOD;Q=(1ll*Q*t[k].p+t[k].q)%MOD;return;}
	int mid=(t[k].l+t[k].r)>>1;
	if(l<=mid)query(k<<1,l,r);
	if(r>mid)query(k<<1|1,l,r);
}	
int main(){
    n=read();m=read();int T=read();
    memset(vis,0,sizeof(vis));
    int kind=0;
    while(T--){//chong ming
    	scanf("%s",s);
    	if(s[0]=='I'){
    		kind++;
    		int l=read(),r=read(),y=read(),p=read(),q=read();
    		b[++tot]=(B){l,y,p,q,kind};
    		b[++tot]=(B){r+1,y,1,0,kind};
    	}
    	else if(s[0]=='D'){
    		int k=read();
    		vis[k]=1;
		}
		else{
			cnt++;a[cnt].x=read();a[cnt].l=read();a[cnt].r=read();a[cnt].id=cnt;
    	}
    }
    sort(b+1,b+tot+1);sort(a+1,a+cnt+1);
    int x=0;
    build(1,1,m);
    for(int i=1;i<=cnt;i++){
    	while(x+1<=tot&&b[x+1].x<=a[i].x){x++;if(!vis[b[x].kind])insert(1,b[x].y,b[x].p,b[x].q);}//if bu duan while
		P=1;Q=0;query(1,a[i].l,a[i].r);
    	ANS[a[i].id]=Q;
    }
    for(int i=1;i<=cnt;i++)printf("%d
",ANS[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/onioncyc/p/9064871.html