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;
    }
  • 相关阅读:
    c# linq.Where+Func<object,bool>筛选数据
    【转】深入线程安全容器的实现方法
    c# 泛型+反射
    c# List<接口>小技巧
    winfrom的右击菜单项事件中如何获取关联控件的引用
    ASP.NET 1.0
    让包含GridView的div或panel的滚动条自己拉到底部怎么做?
    微软的IE中调试JavaScript的工具下载链接
    ASP.NET调试启动默认浏览器如何设置
    C# WinForm的PictureBox控件图片的拉伸或收缩方式跟随着控件的大小
  • 原文地址:https://www.cnblogs.com/wang9897/p/9114456.html
Copyright © 2011-2022 走看看