• 【2018.11.7】【luoguNOIp 热身赛】解题报告及总结


    reference:

    暂告一段落,做的很爽!!
    还剩5题,预计等国庆集训完再回来做

    NOIp热身赛 比赛列表

    P5142 区间方差

    这题挺模板的,暴力单点修改,推一推方差的公式,发现只需要sum和ssum(区间平方和),然后逆元啥的……自己搞(为了练手,用了扩欧,当然ksm也是过得了的)

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    template <typename T>inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;} 
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dwn(i,a,b) for(int i=a;i>=b;--i)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ee(i,u) for(int i=head[u];i;i=e[i].next)
    
    #define lson o<<1
    #define rson o<<1|1
    const int N=100010,mod=1e9+7;
    
    struct tree{
    	int l,r;
    	int sum,ssum;
    }t[N<<2];
    
    int val[N];
    int n,m;
    
    inline void exgcd(int a,int b,int &x,int &y){
    	if(!b)x=1,y=0;
    	else exgcd(b,a%b,y,x),y-=a/b*x;
    }
    
    int inv(int a){
        int x,y;
        exgcd(a,mod,x,y);
        return (x+mod)%mod;
    }
    
    inline void pushup(int o){
    	t[o].sum=(t[lson].sum+t[rson].sum)%mod;
    	t[o].ssum=(t[lson].ssum+t[rson].ssum)%mod;
    }
    
    inline void build(int o,int l,int r){
    	t[o].l=l,t[o].r=r;
    	if(l==r){
    		t[o].sum=val[l]%mod;
    		t[o].ssum=1LL*val[l]*val[l]%mod;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(lson,l,mid);
    	build(rson,mid+1,r);
    	pushup(o);
    }
    
    inline void change(int o,int pos,int k){
    	int l=t[o].l,r=t[o].r;
    	if(pos==l && pos==r){
    		t[o].ssum=1LL*k*k%mod;
    		t[o].sum=k%mod;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	if(pos<=mid)change(lson,pos,k);
    	else change(rson,pos,k);
    	pushup(o);
    }
    
    inline int query_sum(int o,int x,int y){
    	int l=t[o].l,r=t[o].r;
    	if(x<=l && r<=y){
    		return t[o].sum;
    	}
    	int res=0;
    	int mid=(l+r)>>1;
    	if(x<=mid)res=(res+query_sum(lson,x,y))%mod;
    	if(mid<y)res=(res+query_sum(rson,x,y))%mod;
    	return res;
    }
    
    inline int query_ssum(int o,int x,int y){
    	int l=t[o].l,r=t[o].r;
    	if(x<=l && r<=y){
    		return t[o].ssum;
    	}
    	int res=0;
    	int mid=(l+r)>>1;
    	if(x<=mid)res=(res+query_ssum(lson,x,y))%mod;
    	if(mid<y)res=(res+query_ssum(rson,x,y))%mod;
    	return res;
    }
    
    #undef int
    int main(){
    #define int long long
    	#ifdef WIN32
    	freopen("fangcha.txt","r",stdin);
    	#endif 
    	rd(n),rd(m);
    	rep(i,1,n)rd(val[i]);
    	build(1,1,n);
    	while(m--){
    		int op,x,k,y;
    		rd(op);
    		if(op==1){
    			rd(x),rd(k);
    			change(1,x,k);
    		}
    		else if(op==2){
    			rd(x),rd(y);
    			/*
    			方差=(a1^2+a2^2+...+an^2)/n  -  a_ba^2; 
    			*/
    			int len=inv(y-x+1);
    			int sum=query_sum(1,x,y)%mod;
    			int qsum=query_ssum(1,x,y)%mod;
    			qsum=qsum*len%mod;
    			int ba=sum*len%mod;
    			int ave=ba*ba%mod;
    			int ans=qsum-ave;
    			while(ans<0)ans+=mod;//如果不加这句只能得10 pts!!! 
    			printf("%lld
    ",ans);
    		}
    	}
    	return 0;
    }
    

    P1471 方差(上道题的哥哥)

    还要维护一个区间加操作(自己再推一遍如何更新的)

    然鹅最坑的点是加的这个数k是一个实数阿伟调了好久好久!!!!

    主要是update(int o,int x,int y,int k)
    的int k要写成 double k啊我真是个智娃。

    以后看到题上写了实数俩字儿的时候请千万小心!

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;} 
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dwn(i,a,b) for(int i=a;i>=b;--i)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ee(i,u) for(int i=head[u];i;i=e[i].next)
    
    #define lson o<<1
    #define rson o<<1|1
    const int N=100010;
    
    struct tree{
    	int l,r;
    	double sum,ssum,tag_add;
    }t[N<<2];
    
    double val[N];
    int n,m;
    
    inline void pushup(int o){
    	t[o].sum=(t[lson].sum+t[rson].sum);
    	t[o].ssum=(t[lson].ssum+t[rson].ssum);
    }
    
    inline void f(double delta,int o){
    	int l=t[o].l,r=t[o].r;
    	t[o].tag_add+=delta;
    	t[o].ssum=t[o].ssum+2*delta*t[o].sum+delta*delta*(r-l+1);
    	t[o].sum+=delta*(r-l+1);
    } 
    
    inline void pushdown(int o){
    	if(t[o].tag_add){
    		f(t[o].tag_add,lson);
    		f(t[o].tag_add,rson);
    		t[o].tag_add=0;
    	}
    }
    
    inline void build(int o,int l,int r){
    	t[o].tag_add=0;
    	t[o].l=l,t[o].r=r;
    	if(l==r){
    		t[o].sum=val[l];
    		t[o].ssum=val[l]*val[l];
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(lson,l,mid);
    	build(rson,mid+1,r);
    	pushup(o);
    }
    
    inline void update(int o,int x,int y,double k){
    	int l=t[o].l,r=t[o].r;
    	if(x<=l && r<=y){
    		f(k,o);
    		return ;
    	}
    	pushdown(o);
    	int mid=(l+r)>>1;
    	if(x<=mid)update(lson,x,y,k);
    	if(mid<y)update(rson,x,y,k);
    	pushup(o);
    } 
    
    inline double query_sum(int o,int x,int y){
    	int l=t[o].l,r=t[o].r;
    	if(x<=l && r<=y){
    		return t[o].sum;
    	}
    	pushdown(o);
    	double res=0;
    	int mid=(l+r)>>1;
    	if(x<=mid)res=(res+query_sum(lson,x,y));
    	if(mid<y)res=(res+query_sum(rson,x,y));
    	return res;
    }
    
    inline double query_ssum(int o,int x,int y){
    	int l=t[o].l,r=t[o].r;
    	if(x<=l && r<=y){
    		return t[o].ssum;
    	}
    	pushdown(o);
    	double res=0;
    	int mid=(l+r)>>1;
    	if(x<=mid)res=(res+query_ssum(lson,x,y));
    	if(mid<y)res=(res+query_ssum(rson,x,y));
    	return res;
    }
    
    int main(){
    	#ifdef WIN32
    	freopen("fangcha.txt","r",stdin);
    	#endif
    	rd(n),rd(m);
    	rep(i,1,n)scanf("%lf",&val[i]);
    	build(1,1,n);
    	while(m--){
    		int op,x,y;
    		double k;
    		rd(op);
    		if(op==1){
    			rd(x),rd(y);scanf("%lf",&k);
    			update(1,x,y,k);
    		}
    		else if(op==2){
    			rd(x),rd(y);
    			double ans=query_sum(1,x,y)/(y-x+1);
    			printf("%.4lf
    ",ans); 
    		}
    		else if(op==3){
    			rd(x),rd(y);
    			double sum1=query_ssum(1,x,y)/(y-x+1);
    			double sum2=query_sum(1,x,y)/(y-x+1);
    			printf("%.4lf
    ",sum1-sum2*sum2);
    		}
    	}
    	return 0;
    }
    

    P5146 最大差值[胸中的日月]

    智娃水题,由于j>i,所以对于每一个j前的数,最小值是一定的!那么我们存一下minn,不断更新ans=max(ans,x-minn)就可以O(n)啦

    P1890 gcd区间 ST表

    当你,有上线段树的冲动时,不妨看看ST表能不能搞。
    显然,gcd是满足区间可“加”性的。而有没有什么修改操作……ST表无疑是一个酷酷的选择。(而且又好写又好调)

    P2434 [SDOI2005]区间(合并区间模型)

    • 对于每个区间按照左端点从小到大排序
    • 枚举每一个区间;
      • 如果r<rang[i].l的话就输出当前区间(l,r),然后更新l=rang[i].l,r=rang[i].r;,继续去求下一个满足条件的区间。
      • else 说明两个区间有并,则更新r=max(r,range[i].r),其实左端点可以不用更新的(l=min(l,range[i].l),因为毕竟就是按照左端点来排得序嘛
    • 最后不要忘了输出l,r

    P2082 区间覆盖(加强版)上一题的弟弟

    在找到一个符合条件的区间的时候更新一下长度就好啦,没什么难的

    P5077 Tweetuzki 爱等差数列 推公式

    不开long long见祖宗

    手推一下柿子,倒序枚举,找到直接退出(这样可以保证找到的a1是最小的)。

    	rd(s); 
    	int tot=sqrt(2*s)+1;
    	dwn(i,tot,1){
    		if((s*2+i-i*i)%(2*i)==0 && (s*2+i-i*i)/*分母>0,如果不写这句会WA两个点*/){
    			printf("%lld %lld
    ",(s*2+i-i*i)/(2*i),(s*2+i-i*i)/(2*i)+i-1);
    			break;
    		}
    	}
    

    P5144 蜈蚣 前缀异或和+dp

    前缀异或和+dp

    f[i][j]表示前i个位置放了j个^符号(分成了j+1段)

    初值:f[i][0]=sum[i]

    状态转移:
    由区间[1,j-1][j,i]来更新f[i][k]

    rep(i,1,n)
    	rep(k,1,min(m,i-1))
    		rep(j,k,i)
    			f[i][k]=max(f[i][k],f[j-1][k-1]+(sum[i]^sum[j-1]));
    

    P5149 会议座位 归并排序+map

    很明显,在n<=1e5的情况下,逆序对最坏情况下是会达到100000*(100000-1)/2 == 4,999,950,000‬的!!这超出了int 的范围,要开long long.

    不要每次等WA了再重新分析数据范围,要一遍就想明白。考场上不会有提交的feedback!

    P5150 生日礼物 唯一分解定理

    一看见lcm(a,b)==n这么巧!!!
    对于n分解素数,n=p1^c1+p2^c2+p3^c3+...+pn^cn那么对于每一个质数pi,都有max(ci_a,ci_b)=ci;

    开始讨论:当ci_aci,那么b有ci+1种选法(0也要算上),同理,当ci_bci,那么a有ci+1种选法

    加起来是2ci+2种,而当ci_aci_bci的这种情况被算了两边,再-1,得对于每一个素数是2*c[i]+1种,用乘法原理乘起来即可

    不要忘了n本身是一个大质数的情况

  • 相关阅读:
    zbb20181207 springboot @ConfigurationProperties使用
    zbb20181206 logback,lombok 默认日志logback配置解析
    Spring Boot (8) 全局异常处理
    Spring Boot (7) JdbcTemplate访问数据库
    Spring Boot (6) Spring Data JPA
    Spring Boot (4) 静态页面和Thymeleaf模板
    Spring Boot (3) 热部署devtools
    Spring Boot (2) Restful风格接口
    Spring Boot (1) 构建第一个Spring Boot工程
    idea使用maven搭建ssm框架实现登陆商品增删改查
  • 原文地址:https://www.cnblogs.com/sjsjsj-minus-Si/p/11634657.html
Copyright © 2020-2023  润新知