• 【LGR-059】洛谷7月月赛题解


    传送门

    比赛的时候正在大巴上,笔记本没网又没电(不过就算有我估计也不会打就是了)

    (A)

    咕咕

    const int N=(1<<10)+5;
    int a[N][N],n;
    void solve(int x,int y,int p){
    	if(p==1)return a[x][y]=1,void();
    	p>>=1;
    	solve(x+p,y,p),solve(x,y+p,p),solve(x+p,y+p,p);
    }
    int main(){
    	cin>>n,n=(1<<n);
    	solve(1,1,n);
    	fp(i,1,n)fp(j,1,n)printf("%d%c",a[i][j]," 
    "[j==n]);
    	return 0;
    }
    

    (B)

    咕咕

    
    const int N=1e5+5;
    int a[N],b[N],nxt[N],Pre[N],vis[N],n;
    inline void del(R int x){Pre[nxt[x]]=Pre[x],nxt[Pre[x]]=nxt[x];}
    int main(){
    	scanf("%d",&n);
    	fp(i,1,n)scanf("%d",&a[i]),b[a[i]]=i,Pre[i]=i-1,nxt[i]=i+1;
    	fd(i,n,1)if(!vis[i]&&nxt[b[i]]!=n+1){
    		printf("%d %d ",i,a[nxt[b[i]]]),vis[i]=vis[a[nxt[b[i]]]]=1;
    		del(b[i]),del(nxt[b[i]]);
    	}
    	return 0;
    }
    

    (C)

    对于每一对逆序对((i,j))要加上(i imes (n-j+1)),树状数组维护即可,注意这个会爆(long long)所以得开(\_\_int128)

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define ll __int128
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    //typedef long long ll;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    inline void print(R ll x){if(x>9)print(x/10);putchar(x%10+48);}
    const int N=1e6+5;
    ll c[N],res;int a[N],b[N],n,m;
    inline void add(R int x,R int y){for(;x<=m;x+=x&-x)c[x]+=y;}
    inline ll query(R int x){R ll res=0;for(;x;x-=x&-x)res+=c[x];return res;}
    int main(){
    //	freopen("testdata.in","r",stdin); 
    	n=read();
    	fp(i,1,n)a[i]=b[i]=read();
    	sort(b+1,b+1+n),m=unique(b+1,b+1+n)-b-1;
    	fd(i,n,1){
    		a[i]=lower_bound(b+1,b+1+m,a[i])-b;
    		res+=query(a[i]-1)*i,
    		add(a[i],n-i+1);
    	}
    //	printf("%lld
    ",res);	
    	print(res);
    	return 0;
    }
    

    (D)

    转移方程推出来之后暴力都写不对可海星……

    先把所有区间按右端点排序,发现不允许存在一个位置被覆盖三次及以上,且为了不是森林每个节点必须和其他节点中的至少一个有交

    (f_{i,j})表示考虑到第(i)个区间,且选择的上一个区间为(j)的方案数,边界条件为(f_{i,0}=1)

    转移分两种情况,一种是(r[j]geq l[i])(l[j]<l[i]),那么假设此时从(f_{j,k})转移过来,则必须满足的条件是(r[k]<l[i]),即可以写成

    [f_{i,j}=sum_{r[k]<l[i]}f_{j,k} ]

    另一种情况是(r[j]geq l[i])(l[j]geq l[i]),那么就不能从(f[j][k])转移而是应该从(f[i][k])进行转移,且需要满足(r[k]<l[i]),即

    [f_{i,j}=sum_{r[k]<l[j]}f_{i,k} ]

    这两个都可以用树状数组维护

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int P=1e9+7;
    inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R int y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    	return res;
    }
    const int N=4005;
    int l[N],r[N],las[N],id[N],f[N][N],n,mx,res;
    struct BIT{
    	int c[N];
    	inline void ins(R int x,R int y){for(++x;x<=mx;x+=x&-x)upd(c[x],y);}
    	inline int query(R int x){R int res=0;for(++x;x;x-=x&-x)upd(res,c[x]);return res;}
    }bi[N];
    inline bool cmp(const int &x,const int &y){return r[x]==r[y]?l[x]<l[y]:r[x]<r[y];}
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d",&n);
    	fp(i,1,n)scanf("%d%d",&l[i],&r[i]),id[i]=i,cmax(mx,r[i]+1);
    	sort(id+1,id+1+n,cmp);
    	las[1]=1;
    	for(R int i=2,ql,qr,qm,ans;i<=n;++i){
    		ql=1,qr=i-1,ans=i;
    		while(ql<=qr){
    			qm=(ql+qr)>>1;
    			r[id[qm]]>=l[id[i]]?(ans=qm,qr=qm-1):ql=qm+1;
    		}
    		las[i]=ans;
    	}
    	fp(i,1,n)f[i][0]=1,bi[i].ins(0,1),++res;
    	fp(i,2,n)fp(j,las[i],i-1){
    		f[i][j]=(l[id[i]]<=l[id[j]]?bi[i].query(l[id[j]]-1):bi[j].query(l[id[i]]-1));
    		if(f[i][j])bi[i].ins(r[id[j]],f[i][j]),upd(res,f[i][j]);
    //		printf("%d %d %d
    ",i,j,f[i][j]);
    	}
    	printf("%d
    ",res);
    	return 0;
    }
    
  • 相关阅读:
    字符串函数---atof()函数具体解释及实现(完整版)
    curl的简单使用
    [7] 算法之路
    springMVC3.0(文件上传,@RequestMapping加參数,@SessionAttributes,@ModelAttribute,转发,重定向,数值获取,传參,ajax,拦截器)
    hdu 1754 I Hate It 线段树 点改动
    经典的7种排序算法 原理C++实现
    自己定义View实现水平滚动控件
    centos编译ffmpeg x264
    工作脚本处理文本
    A*寻路算法
  • 原文地址:https://www.cnblogs.com/yuanquming/p/11218881.html
Copyright © 2020-2023  润新知