zoukankan      html  css  js  c++  java
  • CodeForces

        假设我们可以对每个位置快速维护一个数组,记录每个位置有哪些值是已经出现了的,哪些值是没有出现的,这样就可以决定修改的时候到底是 *2 还是 +1了。

        但是很可惜,并不存在功能这么强大的数组,所以只能另寻方法啦。。。。

        因为修改总是连续的一段的,所以我们可以发现,对于每个数值来说,被它覆盖的位置也是一段一段的,并且所有数的段数之和<=总的操作数(因为还会发生一些段的合并)。

        所以我们可以对每个数维护一个端点集合set,每次修改的时候就暴力插入一段区间,看一看可以产生多少次合并。

        这样的话,虽然一次修改的复杂度可能会十分之大,但是因为一个端点在贡献一次合并之后就被从 set 里删去了(一次合并只会对应线段树中的一次区间修改),并且每次最多增加两个端点,所以可以证明最后总的复杂度是 O( M * log (N) ),常数略大。。。

        (并且用set维护每个数的区间的时候细节特别多,一定要想清楚了再去写)

        (rank 22/212)

    Discription

    In the School of Magic in Dirtpolis a lot of interesting objects are studied on Computer Science lessons.

    Consider, for example, the magic multiset. If you try to add an integer to it that is already presented in the multiset, each element in the multiset duplicates. For example, if you try to add the integer 22 to the multiset {1,2,3,3}{1,2,3,3}, you will get {1,1,2,2,3,3,3,3}{1,1,2,2,3,3,3,3}.

    If you try to add an integer that is not presented in the multiset, it is simply added to it. For example, if you try to add the integer 44 to the multiset {1,2,3,3}{1,2,3,3}, you will get {1,2,3,3,4}{1,2,3,3,4}.

    Also consider an array of nn initially empty magic multisets, enumerated from 11 to nn.

    You are to answer qq queries of the form "add an integer xx to all multisets with indices l,l+1,,rl,l+1,…,r" and "compute the sum of sizes of multisets with indices l,l+1,,rl,l+1,…,r". The answers for the second type queries can be large, so print the answers modulo 998244353998244353.

    Input

    The first line contains two integers nn and qq (1n,q21051≤n,q≤2⋅105) — the number of magic multisets in the array and the number of queries, respectively.

    The next qq lines describe queries, one per line. Each line starts with an integer tt(1t21≤t≤2) — the type of the query. If tt equals 11, it is followed by three integers ll, rr, xx (1lrn1≤l≤r≤n, 1xn1≤x≤n) meaning that you should add xx to all multisets with indices from ll to rr inclusive. If tt equals 22, it is followed by two integers ll, rr (1lrn1≤l≤r≤n) meaning that you should compute the sum of sizes of all multisets with indices from ll to rr inclusive.

    Output

    For each query of the second type print the sum of sizes of multisets on the given segment.

    The answers can be large, so print them modulo 998244353998244353.

    Examples

    Input
    4 4
    1 1 2 1
    1 1 2 2
    1 1 4 1
    2 1 4
    Output
    10
    Input
    3 7
    1 1 1 3
    1 1 1 3
    1 1 1 2
    1 1 1 1
    2 1 1
    1 1 1 2
    2 1 1
    Output
    4
    8

    Note

    In the first example after the first two queries the multisets are equal to [{1,2},{1,2},{},{}][{1,2},{1,2},{},{}], after the third query they are equal to [{1,1,2,2},{1,1,2,2},{1},{1}][{1,1,2,2},{1,1,2,2},{1},{1}].

    In the second example the first multiset evolves as follows:

    {}{3}{3,3}{2,3,3}{1,2,3,3}{1,1,2,2,3,3,3,3}{}→{3}→{3,3}→{2,3,3}→{1,2,3,3}→{1,1,2,2,3,3,3,3}.

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=200005,ha=998244353;
    #define lc (o<<1)
    #define mid (l+r>>1)
    #define rc ((o<<1)|1)
    inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
    inline void ADD(int &x,int y){ x+=y; if(x>=ha) x-=ha;}
    struct node{
    	int p,id;
    	bool operator <(const node &u)const{
    		return p==u.p?id<u.id:p<u.p;
    	}
    };
    set<node> s[maxn];
    set<node> :: iterator it,her;
    int d[maxn*4],tag[maxn*4],sum[maxn*4];
    int n,m,Q,le,ri,w,len[maxn*4],ans,opt;
    
    inline void maintain(int o){ sum[o]=add(sum[lc],sum[rc]);}
    
    inline void work(int o,int der){
    	ADD(tag[o],der);
    	ADD(sum[o],der*(ll)len[o]%ha);
    }
    
    inline void mul(int o,int der){
    	d[o]=d[o]*(ll)der%ha;
    	tag[o]=tag[o]*(ll)der%ha;
    	sum[o]=sum[o]*(ll)der%ha;
    }
    
    inline void pushdown(int o){
    	if(d[o]!=1){
    		mul(lc,d[o]),mul(rc,d[o]);
    		d[o]=1;
    	}
    	
    	if(tag[o]){
    		work(lc,tag[o]),work(rc,tag[o]);
    		tag[o]=0;
    	}
    }
    
    void build(int o,int l,int r){
    	d[o]=1,len[o]=r-l+1;
    	if(l==r) return;
    	build(lc,l,mid);
    	build(rc,mid+1,r);
    }
    
    void umul(int o,int l,int r){
    	if(l>=le&&r<=ri){ mul(o,2); return;}
    	pushdown(o);
    	if(le<=mid) umul(lc,l,mid);
    	if(ri>mid) umul(rc,mid+1,r);
    	maintain(o);
    }
    
    void uadd(int o,int l,int r){
    	if(l>=le&&r<=ri){ work(o,w); return;}
    	pushdown(o);
    	if(le<=mid) uadd(lc,l,mid);
    	if(ri>mid) uadd(rc,mid+1,r);
    	maintain(o);
    }
    
    void query(int o,int l,int r){
    	if(l>=le&&r<=ri){ ADD(ans,sum[o]); return;}
    	pushdown(o);
    	if(le<=mid) query(lc,l,mid);
    	if(ri>mid) query(rc,mid+1,r);
    }
    
    void Change(int num,int L,int R){	
        set<node> &S=s[num];
        
        int fl=L,fr=R;
        
        it=S.lower_bound((node){L,0});
        
        for(w=1;L<=R;it=S.lower_bound((node){L,0})){
        	if(it==S.end()){
        		le=L,ri=R,uadd(1,1,n);
        		break;
    		}
        	else if(it->id){
        		le=L,ri=min(it->p,R),umul(1,1,n);
        		L=ri+1;
    			if(R>=it->p) S.erase(it);
    		}
    		else{
    			le=L,ri=min(it->p-1,R);
    			if(le<=ri) uadd(1,1,n);
    			L=ri+1;
    			if(R>=it->p) S.erase(it);
    		}
    	}
    	
    	it=S.lower_bound((node){fl,0});
    	her=S.lower_bound((node){fr,1});
    	
    	if(it==S.begin()||(--it)->id) S.insert((node){fl,0});
    	if(her==S.end()||!her->id) S.insert((node){fr,1});
    }
    
    inline void solve(){
    	build(1,1,n);
    	
    	while(Q--){
    		scanf("%d",&opt);
    		if(opt==1){
    			scanf("%d%d%d",&le,&ri,&w);
    			Change(w,le,ri);
    		}
    		else{
    		    scanf("%d%d",&le,&ri),ans=0;
    		    query(1,1,n),printf("%d
    ",ans);
    		}
    	}
    }
    
    int main(){
    	scanf("%d%d",&n,&Q);
    	solve();
    	return 0;
    }
    

      

  • 相关阅读:
    arcgis pro加载其他数据
    ArcGIS Pro运行Python脚本
    获得ArcGIS Pro的版本
    ArcGIS Pro使用键盘控制地图平移
    ArcGIS Pro添加注记工具
    ArcGIS Pro二次开发添加网络图层
    ArcGIS Pro放大缩小按钮
    ArcGIS Pro做一个矩形选择按钮
    ArcGIS Pro获得一个图层的样式
    ArcGIS Pro二次开发闪烁对象
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9110639.html
Copyright © 2011-2022 走看看