zoukankan      html  css  js  c++  java
  • ODT&(Avito Code Challenge 2018 G题)

    记录大模拟一般新数据结构(ODT)

    #include <bits/stdc++.h>
    #define ll long long
    #define pii pair<int,int>
    #define s second
    #define f first
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=2e5+10;
    const ll mod=998244353;
    using namespace std;
    ll read(){  
        ll x=0,f=1;char ch=getchar();  
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}  
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();  
        return f*x;  
    }
    set<pii>s[MAXN];
    set<pii>::iterator ite,ip,id;
    int n,q;
    typedef struct node{
    	ll tag1,tag2,sum;int l,r;
    }node;
    node d[MAXN<<2];
    void push(int x){
    	if(d[x].tag1>1){
    		d[x<<1].tag1*=d[x].tag1;d[x<<1].tag1%=mod;
    		d[x<<1|1].tag1*=d[x].tag1;d[x<<1|1].tag1%=mod;
    		d[x<<1].tag2*=d[x].tag1;d[x<<1].tag2%=mod;
    		d[x<<1|1].tag2*=d[x].tag1;d[x<<1|1].tag2%=mod;
    		d[x<<1].sum*=d[x].tag1;d[x<<1].sum%=mod;
    		d[x<<1|1].sum*=d[x].tag1;d[x<<1|1].sum%=mod;
    		d[x].tag1=1; 
    	}
    	if(d[x].tag2){
    		d[x<<1].tag2+=d[x].tag2;d[x<<1].tag2%=mod;
    		d[x<<1|1].tag2+=d[x].tag2;d[x<<1|1].tag2%=mod;
    		d[x<<1].sum+=1ll*(d[x<<1].r-d[x<<1].l+1)*d[x].tag2;
    		d[x<<1].sum%=mod;
    		d[x<<1|1].sum+=1ll*(d[x<<1|1].r-d[x<<1|1].l+1)*d[x].tag2;
    		d[x<<1|1].sum%=mod;
    		d[x].tag2=0;
    	}
    }
    void up(int x){d[x].sum=d[x<<1].sum+d[x<<1|1].sum;}
    void built(int rt,int l,int r){
    	if(l==r){d[rt].l=d[rt].r=l;d[rt].tag1=1;d[rt].tag2=d[rt].sum=0;return ;}
    	int mid=(l+r)>>1;
    	built(rt<<1,l,mid);
    	built(rt<<1|1,mid+1,r);
    	d[rt].l=d[rt<<1].l;d[rt].r=d[rt<<1|1].r;
    	d[rt].tag1=1;d[rt].tag2=d[rt].sum=0;
    	up(rt);
    }
    void update1(int rt,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr){
    		d[rt].tag1*=2ll;d[rt].tag2*=2ll;d[rt].sum*=2ll;
    		d[rt].tag1%=mod;d[rt].tag2%=mod;d[rt].sum%=mod;
    		return ;
    	}
    	push(rt);
    	int mid=(l+r)>>1;
    	if(ql<=mid)update1(rt<<1,l,mid,ql,qr);
    	if(qr>mid)update1(rt<<1|1,mid+1,r,ql,qr);
    	up(rt);
    }
    //新建 
    void update2(int rt,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr){
    		d[rt].tag2+=1ll;d[rt].sum+=1ll*(r-l+1);
    		d[rt].tag2%=mod;d[rt].sum%=mod;
    		return ;
    	}
    	push(rt);
    	int mid=(l+r)>>1;
    	if(ql<=mid)update2(rt<<1,l,mid,ql,qr);
    	if(qr>mid)update2(rt<<1|1,mid+1,r,ql,qr);
    	up(rt);
    }
    ll sum=0;
    void querty(int rt,int l,int r,int ql,int qr){
    	if(ql<=l&&r<=qr){
    		sum+=d[rt].sum;sum%=mod;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	push(rt);
    	if(ql<=mid)querty(rt<<1,l,mid,ql,qr);
    	if(qr>mid)querty(rt<<1|1,mid+1,r,ql,qr);
    	up(rt);
    }
    int main(){
    	n=read();q=read(); 
    	built(1,1,n);
    	int op,l,r,vul;
    	for(int i=1;i<=q;i++){
    		op=read();l=read();r=read();
    		if(op==1){
    			vul=read();int flag1=0,flag2=0;
    			ite=s[vul].lower_bound(make_pair(l,0));
    			if(s[vul].begin()==s[vul].end()){
    				s[vul].insert(make_pair(l,r));
    				update2(1,1,n,l,r);
    				continue;
    			}
    			//	cout<<ite->first<<" "<<ite->second<<endl;
    		//	cout<<s[vul].size()<<"----"<<endl;
    			if(ite==s[vul].end()){
    				//cout<<"sb"<<endl;
    				ite--;
    				if(ite->second<l){
    				s[vul].insert(make_pair(l,r));
    				update2(1,1,n,l,r);
    				continue;					
    				}
    				else{
    					int l1=ite->first;int r1=ite->second;
    					s[vul].erase(make_pair(l1,r1));
    					s[vul].insert(make_pair(l1,l-1));
    					s[vul].insert(make_pair(l,r1));
    				}
    			}
    			else if(ite==s[vul].begin()&&ite->first!=l){
    			//	cout<<"AC"<<endl;
    				if(r<ite->first){
    					s[vul].insert(make_pair(l,r));
    					update2(1,1,n,l,r);continue;
    				}
    				else{
    					flag1=1;
    					//cout<<"AC"<<endl;
    					//cout<<ite->first<<" "<<ite->second<<endl;
    					s[vul].insert(make_pair(l,ite->first-1));
    					update2(1,1,n,l,ite->first-1);
    				}
    			}
    			else if(ite->first!=l){
    				//cout<<ite->first<<" "<<ite->second<<endl;
    				int lx=ite->first;ite--;
    				if(ite->second<l){
    					flag1=1;
    					if(lx<=r){
    					s[vul].insert(make_pair(l,lx-1));
    					update2(1,1,n,l,lx-1);}
    					else{
    						s[vul].insert(make_pair(l,r));
    						update2(1,1,n,l,r);
    						continue;
    					}
    				}
    				else{
    					int l1=ite->first;int r1=ite->second;
    					//cout<<l1<<" "<<r1<<endl;
    					s[vul].erase(make_pair(l1,r1));
    					s[vul].insert(make_pair(l1,l-1));
    					s[vul].insert(make_pair(l,r1));
    				}
    			}
    		//	cout<<"SB"<<endl;
    			ip=s[vul].lower_bound(make_pair(r,0));
    			//if(ip==s[vul].end())cout<<"Yes"<<endl;
    			//cout<<ip->first<<" "<<ip->second<<endl;
    			if(ip==s[vul].end()||ip->first>r){
    				ip--;
    				if(ip->second<r){
    					flag2=1;
    					//cout<<"AC"<<endl;
    					//cout<<ip->second<<endl;
    					update2(1,1,n,ip->second+1,r);
    					//if(r==ip->second+1)s[vul].insert(make_pair(r,r));
    					if(r!=ip->second+1) s[vul].insert(make_pair(ip->second+1,r-1)),flag2=2;
    					s[vul].insert(make_pair(r,r));
    				}
    				else{
    					int l1=ip->first;int r1=ip->second;
    					//cout<<l1<<" "<<r1<<endl;
    					s[vul].erase(make_pair(l1,r1));
    					if(l1!=r) s[vul].insert(make_pair(l1,r-1));
    					s[vul].insert(make_pair(r,r));
    					if(r!=r1) s[vul].insert(make_pair(r+1,r1));
    				}
    			}
    			else{
    				int l1=ip->first;int r1=ip->second;
    				//cout<<l1<<" "<<r1<<endl;
    				s[vul].erase(make_pair(l1,r1));
    				s[vul].insert(make_pair(r,r));
    				if(r!=r1) s[vul].insert(make_pair(r+1,r1));
    			}
    			ite=s[vul].lower_bound(make_pair(l,0));
    			ip=s[vul].lower_bound(make_pair(r,0));
    			if(flag2==2)ip--;
    			//cout<<ite->first<<" "<<ite->second<<endl;
    			//cout<<flag1<<endl;
    			id=s[vul].end();
    			if(!flag1) update1(1,1,n,ite->first,ite->second);
    			//else id=ite;
    			id=ite;ite++;
    			//cout<<flag1<<endl;
    			if(ite!=s[vul].end()&&id!=ip){
    			//cout<<"AC"<<endl;
    			for(;ite!=ip;ite++){
    				//cout<<"sb"<<endl;
    				if(ite->first-id->second>1){
    					update2(1,1,n,id->second+1,ite->first-1);
    				}
    				update1(1,1,n,ite->first,ite->second);
    				id=ite;
    			}
    			if(ip->first-id->second>1){
    				//cout<<"sb"<<endl;
    				update2(1,1,n,id->second+1,ip->first-1);			
    			}
    			if(!flag2) update1(1,1,n,ip->first,ip->second);}
    			//cout<<flag2<<endl;
    			ite=s[vul].lower_bound(make_pair(l,0));
    			ip=s[vul].lower_bound(make_pair(r,0));
    			ip++;
    			s[vul].erase(ite,ip);
    			s[vul].insert(make_pair(l,r));
    		}
    		else{
    			sum=0;
    			//cout<<l<<" "<<r<<endl;
    			querty(1,1,n,l,r);
    			printf("%lld
    ",sum);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 136 只出现一次的数字
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 135 分发糖果
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 134 加油站
    Java实现 LeetCode 133 克隆图
  • 原文地址:https://www.cnblogs.com/wang9897/p/9114456.html
Copyright © 2011-2022 走看看