zoukankan      html  css  js  c++  java
  • P5350 【序列】

    看见一堆人在喷swap毒瘤,其实swap很好写啊。

    首先,先在输入后面加上这么一句话:

    s.insert(node(n+1,n+n+5,0));
        
    

    在这个序列后加一个长为n的空序列。

    然后保证您的Copy是对的

    Copy可以这么写:

    void Copy(int l1,int r1,int l2,int r2) {
    	IT itr=Split(r1+1),itl=Split(l1);
    	for(tot=0;itl!=itr;++itl)
    		a[++tot]=l2+itl->l-l1,b[tot]=l2+itl->r-l1,c[tot]=itl->val;
    	for(int i=1;i<=tot;++i)
    		Assign(a[i],b[i],c[i]);
    }
    

    大概就是存一下Copy过去对应的区间是什么,然后Assign过去就好了。少对指针操作,因为指针太玄学了qwq

    接着Swap,看看代码就能懂……

    void Swap(int l1,int r1,int l2,int r2) {
    	Copy(l1,r1,n+1,n+r1-l1+1);
    	Copy(l2,r2,l1,r1);
    	Copy(n+1,n+r1-l1+1,l2,r2);
    }
    

    真的一点都不毒瘤!!!

    只要您能理解swap整数时的内部操作:

    void swap(int &a,int &b) {
        int tmp;
        tmp=a;
        a=b;
        b=tmp;
    }
    

    然后区间加,区间求和,区间推平都不讲了。

    区间翻转

    先看代码,看懂了就不用看说明了。

    void Reverse(int l,int r) {
    	IT itr=Split(r+1),itl=Split(l);
    	vector<node>vec;
    	for(IT it=itl;it!=itr;++it)
    		vec.push_back(node(it->l,it->r,it->val));
    	s.erase(itl,itr);
    	int t=l;
    	for(int i=vec.size()-1;i>=0;--i)
    		s.insert(node(t,t+vec[i].r-vec[i].l,vec[i].val)),t+=vec[i].r-vec[i].l+1;
    }
    

    说明:就是先把节点存起来,把区间删掉,然后把节点倒着插回去。

    其实我感觉ODT的操作都很好懂,因为全是暴力……

    然后关于输出,由于每个节点存的是区间,所以要考虑如何输出区间长度遍。然后瞎搞搞出来了一个东西……

    void Print(){
    	IT it=s.begin();
    	int print=0;
    	while(print<n) {
    		for(int i=it->l;i<=it->r;++i)
    		{
    			printf("%lld ",it->val);
    			++print;
    			if(print==n)return (void)puts("");
    		}
    		++it;
    	}
    }
    

    完整版代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int mod=1000000007;
    const int N=300005;
    int n,m;
    struct node {
    	int l,r;
    	mutable int val;
    	node(int L,int R=-1,int V=0):l(L),r(R),val(V){}
    	bool operator < (const node &rhs)const{return l<rhs.l;}
    };
    set<node>s;
    #define IT set<node>::iterator
    void Print(){
    	IT it=s.begin();
    	int print=0;
    	while(print<n) {
    		for(int i=it->l;i<=it->r;++i)
    		{
    			printf("%lld ",it->val);
    			++print;
    			if(print==n)return (void)puts("");
    		}
    		++it;
    	}
    }
    IT Split(int pos){
    	IT it=s.lower_bound(node(pos));
    	if(it!=s.end()&&it->l==pos)return it;
    	--it;
    	int ll=it->l,rr=it->r,v=it->val;
    	s.erase(it);
    	s.insert(node(ll,pos-1,v));
    	return s.insert(node(pos,rr,v)).first;
    }
    int Sum(int l,int r){
    	int res=0;
    	IT itr=Split(r+1),itl=Split(l);
    	for(;itl!=itr;++itl)
    		res=(res+(itl->r-itl->l+1)*itl->val)%mod;
    	return (int)res;
    }
    void Assign(int l,int r,int val) {
    	IT itr=Split(r+1),itl=Split(l);
    	s.erase(itl,itr);
    	s.insert(node(l,r,val));
    }
    void Add(int l,int r,int val) {
    	IT itr=Split(r+1),itl=Split(l);
    	for(;itl!=itr;++itl)
    		itl->val=(itl->val+val)%mod;
    }
    int a[N],b[N],c[N],tot;
    void Copy(int l1,int r1,int l2,int r2) {
    	IT itr=Split(r1+1),itl=Split(l1);
    	for(tot=0;itl!=itr;++itl)
    		a[++tot]=l2+itl->l-l1,b[tot]=l2+itl->r-l1,c[tot]=itl->val;
    	for(int i=1;i<=tot;++i)
    		Assign(a[i],b[i],c[i]);
    }
    void Swap(int l1,int r1,int l2,int r2) {
    	Copy(l1,r1,n+1,n+r1-l1+1);
    	Copy(l2,r2,l1,r1);
    	Copy(n+1,n+r1-l1+1,l2,r2);
    }
    void Reverse(int l,int r) {
    	IT itr=Split(r+1),itl=Split(l);
    	vector<node>vec;
    	for(IT it=itl;it!=itr;++it)
    		vec.push_back(node(it->l,it->r,it->val));
    	s.erase(itl,itr);
    	int t=l;
    	for(int i=vec.size()-1;i>=0;--i)
    		s.insert(node(t,t+vec[i].r-vec[i].l,vec[i].val)),t+=vec[i].r-vec[i].l+1;
    }
    signed main() {
    	scanf("%lld%lld",&n,&m);
    	for(int i=1,x;i<=n;++i)
    		scanf("%d",&x),s.insert(node(i,i,x));
    	s.insert(node(n+1,n+n+5,0));
    	while(m--) {
    		int opt;
    		scanf("%lld",&opt);
    		if(opt==1) {
    			int l,r;
    			scanf("%lld%lld",&l,&r);
    			printf("%d
    ",Sum(l,r));
    			//Print();
    		}
    		if(opt==2) {
    			int l,r,val;
    			scanf("%lld%lld%lld",&l,&r,&val);
    			Assign(l,r,val);
    			//Print();
    		}
    		if(opt==3) {
    			int l,r,val;
    			scanf("%lld%lld%lld",&l,&r,&val);
    			Add(l,r,val);
    			//Print();
    		}
    		if(opt==4) {
    			int l1,r1,l2,r2;
    			scanf("%lld%lld%lld%lld",&l1,&r1,&l2,&r2);
    			Copy(l1,r1,l2,r2);
    			//Print();
    			}
    		if(opt==5) {
    			int l1,r1,l2,r2;
    			scanf("%lld%lld%lld%lld",&l1,&r1,&l2,&r2);
    			Swap(l1,r1,l2,r2);
    			//Print();
    		}
    		if(opt==6) {
    			int l,r;
    			scanf("%lld%lld",&l,&r);
    			Reverse(l,r);
    			//Print();
    		}
    	}
    	Print();
    	return 0;
    }
    
    路漫漫其修远兮,吾将上下而求索
  • 相关阅读:
    [恢]hdu 2116
    [恢]hdu 1203
    [恢]hdu 1181
    [恢]hdu 1280
    [恢]hdu 1250
    [恢]hdu 1215
    [恢]hdu 1237
    [恢]hdu 1276
    PowerShell yarn : 无法加载文件 C:\Users\Admin\AppData\Roaming\npm\yarn.ps1,因为在此系统因为在此系统上禁止运行脚本。
    vue : 无法加载文件 C:\Users\1111111\AppData\Roaming\npm\vue.ps1,因为在此系统禁止运行脚本
  • 原文地址:https://www.cnblogs.com/zzctommy/p/12918547.html
Copyright © 2011-2022 走看看