zoukankan      html  css  js  c++  java
  • 一本通1755:星际探测

    链接

    (k) 很小,建一个线段树,(O(k^2)) 合并。
    询问时查找区间最小值的位置,合并去掉最小值的左右两段区间。

    #include<bits/stdc++.h>
    #define IL inline
    #define ls k<<1
    #define rs k<<1|1
    #define LL unsigned int
    using namespace std;
    const int N=1e5+3;
    LL n,m,fac[10];
    struct kk{
    	LL d,v;
    	bool operator<(const kk &a) const{
    	return d<a.d;}
    }a[N];
    struct hh{
    	 LL f[7]={1};
    	 void clear(){memset(f,0,sizeof(f)),f[0]=1;}
    };
    hh operator+(const hh &a,const hh &b){
    	hh c;c.clear();
    	for(int i=1;i<=6;++i)
    	  for(int j=0;j<=i;++j)
    	    c.f[i]+=a.f[j]*b.f[i-j];
    	return c;
    }
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    } 
    struct segment{
    	int Min[N<<2],pos[N<<2];
    	hh f[N<<2];
    	IL void pushup(int k){
    		if(Min[ls]<Min[rs]) Min[k]=Min[ls],pos[k]=pos[ls];
    		else Min[k]=Min[rs],pos[k]=pos[rs];
    		f[k]=f[ls]+f[rs];
    	}
    	void build(int k,int l,int r){
    		if(l==r){Min[k]=a[l].v,pos[k]=l,f[k].f[1]=a[l].v;return;}
    		int mid=l+r>>1;
    		build(ls,l,mid),build(rs,mid+1,r);
    		pushup(k);
    	}
    	int ask1(int k,int l,int r,int ll,int rr){
    		if(l>=ll&&r<=rr) return pos[k];
    		int mid=l+r>>1;
    		if(rr<=mid) return ask1(ls,l,mid,ll,rr);
    		if(ll>mid) return ask1(rs,mid+1,r,ll,rr);
    		int lc=ask1(ls,l,mid,ll,rr),rc=ask1(rs,mid+1,r,ll,rr);
    		return a[lc].v<a[rc].v?lc:rc;
    	}
    	hh ask2(int k,int l,int r,int ll,int rr){
    		if(l>=ll&&r<=rr) return f[k];
    		int mid=l+r>>1;
    		hh lc,rc;lc.clear(),rc.clear();
    		if(ll<=mid) lc=ask2(ls,l,mid,ll,rr);
    		if(rr>mid) rc=ask2(rs,mid+1,r,ll,rr);
    		return lc+rc;
    	}
    	hh query(int l,int r,int k){
    		int pos=ask1(1,1,n,l,r);
    		hh lc,rc;lc.clear(),rc.clear();
    		if(l<=pos-1) lc=ask2(1,1,n,l,pos-1);
    		if(pos+1<=r) rc=ask2(1,1,n,pos+1,r);
    		return lc+rc;
    	}
    }T;
    int main()
    {
    	int l,r,k;
    	n=in(),m=in();
    	fac[0]=1;for(int i=1;i<=6;++i) fac[i]=fac[i-1]*i;
    	for(int i=1;i<=n;++i) a[i].d=in();
    	for(int i=1;i<=n;++i) a[i].v=in();
    	sort(a+1,a+n+1);
    	T.build(1,1,n);
    	for(int i=1;i<=m;++i){
    		l=in(),r=in(),k=in();
    		l=lower_bound(a+1,a+n+1,(kk){l,0})-a,
    		r=upper_bound(a+1,a+n+1,(kk){r,0})-a-1;
    		if(l>r){printf("0
    ");continue;}
    		hh ans=T.query(l,r,k);
    		printf("%u
    ",ans.f[k]*fac[k]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    4.JDBC编程
    android 多线程
    android 网络请求Ⅰ
    android 数据存储Ⅱ
    android 数据存储Ⅰ
    android 界面设计基本知识Ⅳ
    《将博客搬至CSDN》
    android 界面设计基本知识Ⅲ
    android 界面设计基本知识Ⅱ
    android 界面设计基本知识
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/13914967.html
Copyright © 2011-2022 走看看