zoukankan      html  css  js  c++  java
  • 【计蒜客】贝壳找房户外拓展(中等)扫描线+线段树

    【题目】贝壳找房户外拓展(中等)
    【题意】给定(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;
    }
  • 相关阅读:
    20170416
    汇总02
    总结
    在编程的世界中,如何高效地学习理论知识,应用理论知识来解决实际生产中的问题
    周末待整理
    web 性能提升
    es6
    http、https、 json、 ajax
    微信小程序 问题收集
    eslint
  • 原文地址:https://www.cnblogs.com/onioncyc/p/9064871.html
Copyright © 2011-2022 走看看