zoukankan      html  css  js  c++  java
  • NOIOL #2 爆零记

    没有假是真的爆零了,原因:万恶的文操。不管怎样写份题解吧。

    T1:

    做题经历:看了下题发现:不是 edu 的原题吗?兴奋地拿出赛中写的程序搞上去。
    大约比赛开始 30min 后开始发现 (k) 可以等于 (1),然后急忙特判了个 (1) 就没了。
    预计得分(不计文操):100

    题解:
    由于 (operatorname{lcm}(p1,p2) le 10^{20}),所以我们可以将带子的长度看做 (infty)
    不妨设 (p_1<p_2)
    显然最长的一段连续的相同的色块只可能是红色。
    那么我们肯定要贪心的将公共部分染成蓝色。
    这样题目就转化为:是否存在整数 (a) 使得 ([ap_2+1,(a+1)p_2-1])(p_1) 的个数 (geq k)
    由于 (p1)(p2) 不一定互质,可以将它们都除以它们的 (gcd)
    根据扩展欧几里得,一定存在正整数 (x,y) 使得 (xp_1-yp_2=1)。那么我们需检查 ([yp_2+1,(y+1)p_2-1]) 中是否有 (geq k)(p_1) 的倍数。
    这可以用 ( exttt{exgcd}) 求出,不过进一步发现这里的 (x,y) 是什么不重要,因为 (yp_2+1) 已经是一个 (p_2) 的倍数,我们只需比较 ((x+k-1)p_1+1)((y+1)p_2-1) 的关系,即 ((k-1)p_1+2)(p_2) 的关系。如果 ((k-1)p_1+2 leq p_2),答案为 No;反之答案为 Yes。
    注意判 (k=1)

    //Coded by tzc_wk
    /*
    数据不清空,爆零两行泪。
    多测不读完,爆零两行泪。
    边界不特判,爆零两行泪。
    贪心不证明,爆零两行泪。
    D P 顺序错,爆零两行泪。
    大小少等号,爆零两行泪。
    变量不统一,爆零两行泪。
    越界不判断,爆零两行泪。
    调试不注释,爆零两行泪。
    溢出不 l l,爆零两行泪。
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define fi			first
    #define se			second
    #define fz(i,a,b)	for(int i=a;i<=b;i++)
    #define fd(i,a,b)	for(int i=a;i>=b;i--)
    #define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
    #define all(a)		a.begin(),a.end()
    #define giveup(...) return printf(__VA_ARGS__),0;
    #define fill0(a)	memset(a,0,sizeof(a))
    #define fill1(a)	memset(a,-1,sizeof(a))
    #define fillbig(a)	memset(a,0x3f,sizeof(a))
    #define fillsmall(a) memset(a,0xcf,sizeof(a))
    #define mask(a)		(1ll<<(a))
    #define maskx(a,x)	((a)<<(x))
    #define _bit(a,x)	(((a)>>(x))&1)
    #define _sz(a)		((int)(a).size())
    #define filei(a)	freopen(a,"r",stdin);
    #define fileo(a)	freopen(a,"w",stdout);
    #define fileio(a) 	freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    #define eprintf(...) fprintf(stderr,__VA_ARGS__)
    #define put(x)		putchar(x)
    #define eoln        put('
    ')
    #define space		put(' ')
    #define y1			y_chenxiaoyan_1
    #define y0			y_chenxiaoyan_0
    #define int long long
    typedef pair<int,int> pii;
    inline int read(){
    	int x=0,neg=1;char c=getchar();
    	while(!isdigit(c)){
    		if(c=='-')	neg=-1;
    		c=getchar();
    	}
    	while(isdigit(c))	x=x*10+c-'0',c=getchar();
    	return x*neg;
    }
    inline void print(int x){
    	if(x<0){
    		putchar('-');
    		print(abs(x));
    		return;
    	}
    	if(x<=9)	putchar(x+'0');
    	else{
    		print(x/10);
    		putchar(x%10+'0');
    	}
    }
    inline int qpow(int x,int e,int _MOD){
    	int ans=1;
    	while(e){
    		if(e&1)	ans=ans*x%_MOD;
    		x=x*x%_MOD;
    		e>>=1;
    	}
    	return ans;
    }
    signed main(){
    	int T=read();
    	while(T--){
    		int x=read(),y=read(),z=read();
    		if(z==1){
    			puts("No");
    			continue;
    		}
    		int gcd=__gcd(x,y);
    		x/=gcd;y/=gcd;
    //		cout<<x<<" "<<y<<endl;
    		if(x*(z-1)+2<=y||y*(z-1)+2<=x)	puts("No");
    		else							puts("Yes");
    	}
    	return 0;
    }
    /*
    3 4 6 8 9 12
    */
    

    T2:

    做题经历:50 分做法太水不过了,不能满足我的要求,因此一直在想满分做法。
    想了 (~25) min,想到了一个线段树做法,就开始写。
    写+调大约共用时 (30) 分钟。然后造极端数据发现跑了 3000ms /fad
    疯狂卡常,耗在卡常上的时间堪比写程序的时间。register、inline 什么的全用上了,然后也没有发现明显的优化效果。
    据说是取模的常数大?
    预计得分(不计文操):70~100(不知道 CCF 数据毒不毒)

    题解:
    首先值域是 (10^9) 就暗示着需要离散化。
    我们枚举左端点 (l),考虑当左端点为 (l) 的区间对答案的贡献,把这些贡献全部加在一起就是最终的答案。
    题目就简化为求 (sumlimits_{i=l}^n f(l,i)^2)
    对于 ([l,n]) 中出现过的 (x),我们找出它在 ([l,n]) 中出现最靠左的位置 (pos_x)。我们记 (t_i)(f(l,i)) 的值。倒着循环 (l),考虑左端点从 (l+1) 变为 (l) 的影响,假设原来的 (pos_{a_l})(l'),那么会发生以下两件事:

    1. (pos_{a_l}) 会变为 (l)
    2. (t_l,t_{l+1},dots,t_{l'-1}) 的值将全部加 (1)。因为 (a_l) 这个数在 ([l+1,l],[l+1,l+1],dots,[l+1,l'-1]) 中没有出现过,而在 ([l,l],[l,l+1],dots,[l,l'-1]) 出现过了。
      那么现在就变成了下面的问题:
    • 区间加某个数
    • 求区间中所有数平方的和
      这个可以用线段树来实现。考虑区间加上某个数 (k),那么平方和变为:

    [(a_l+k)^2+(a_{l+1}+k)^2+dots+(a_r+k)^2 ]

    [=a_l^2+2ka_l+k^2+a_{l+1}^2+2ka_{l+1}+k^2+dots+a_r^2+2ka_r+k^2 ]

    [=(a_l^2+a_{l+1}^2+dots+a_r^2)+2k(a_l+a_{l+1}+dots+a_r)+(r-l+1) imes k^2 ]

    维护区间平方和和区间和就可以做到 (mathcal O(1)) 更新了。

    //Coded by tzc_wk
    /*
    数据不清空,爆零两行泪。
    多测不读完,爆零两行泪。
    边界不特判,爆零两行泪。
    贪心不证明,爆零两行泪。
    D P 顺序错,爆零两行泪。
    大小少等号,爆零两行泪。
    变量不统一,爆零两行泪。
    越界不判断,爆零两行泪。
    调试不注释,爆零两行泪。
    溢出不 l l,爆零两行泪。
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define fi			first
    #define se			second
    #define fz(i,a,b)	for(register int i=a;i<=b;i++)
    #define fd(i,a,b)	for(register int i=a;i>=b;i--)
    #define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
    #define all(a)		a.begin(),a.end()
    #define giveup(...) return printf(__VA_ARGS__),0;
    #define fill0(a)	memset(a,0,sizeof(a))
    #define fill1(a)	memset(a,-1,sizeof(a))
    #define fillbig(a)	memset(a,0x3f,sizeof(a))
    #define fillsmall(a) memset(a,0xcf,sizeof(a))
    #define mask(a)		(1ll<<(a))
    #define maskx(a,x)	((a)<<(x))
    #define _bit(a,x)	(((a)>>(x))&1)
    #define _sz(a)		((int)(a).size())
    #define filei(a)	freopen(a,"r",stdin);
    #define fileo(a)	freopen(a,"w",stdout);
    #define fileio(a) 	freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    #define eprintf(...) fprintf(stderr,__VA_ARGS__)
    #define put(x)		putchar(x)
    #define eoln        put('
    ')
    #define space		put(' ')
    #define y1			y_chenxiaoyan_1
    #define y0			y_chenxiaoyan_0
    #define int long long
    typedef pair<int,int> pii;
    inline int read(){
    	int x=0,neg=1;char c=getchar();
    	while(!isdigit(c)){
    		if(c=='-')	neg=-1;
    		c=getchar();
    	}
    	while(isdigit(c))	x=x*10+c-'0',c=getchar();
    	return x*neg;
    }
    inline void print(int x){
    	if(x<0){
    		putchar('-');
    		print(abs(x));
    		return;
    	}
    	if(x<=9)	putchar(x+'0');
    	else{
    		print(x/10);
    		putchar(x%10+'0');
    	}
    }
    inline int qpow(int x,int e,int _MOD){
    	int ans=1;
    	while(e){
    		if(e&1)	ans=ans*x%_MOD;
    		x=x*x%_MOD;
    		e>>=1;
    	}
    	return ans;
    }
    const int MOD=1e9+7;
    int n,a[1000005],key[1000005],hs[1000005],cnt=0;
    struct node{
    	int l,r;
    	int sum,sqr;
    	int lz;
    } s[1000005<<2];
    inline void build(int k,int l,int r){
    	s[k].l=l;s[k].r=r;
    	if(l==r)	return;
    	int mid=(l+r)>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    }
    inline void pushup(int k){
    	s[k].sqr=s[k<<1].sqr+s[k<<1|1].sqr;
    	if(s[k].sqr>MOD)	s[k].sqr-=MOD;
    	s[k].sum=s[k<<1].sum+s[k<<1|1].sum;
    	if(s[k].sum>MOD)	s[k].sum-=MOD;
    }
    inline void pushdown(int k){
    	if(!s[k].lz)	return;
    	s[k<<1].sqr=(s[k<<1].sqr+2*s[k].lz*s[k<<1].sum+(s[k<<1].r-s[k<<1].l+1)*s[k].lz*s[k].lz)%MOD;
    	s[k<<1].sum=(s[k<<1].sum+(s[k<<1].r-s[k<<1].l+1)*s[k].lz)%MOD;
    	s[k<<1].lz+=s[k].lz;
    	s[k<<1|1].sqr=(s[k<<1|1].sqr+2*s[k].lz*s[k<<1|1].sum+(s[k<<1|1].r-s[k<<1|1].l+1)*s[k].lz*s[k].lz)%MOD;
    	s[k<<1|1].sum=(s[k<<1|1].sum+(s[k<<1|1].r-s[k<<1|1].l+1)*s[k].lz)%MOD;
    	s[k<<1|1].lz+=s[k].lz;
    	s[k].lz=0;
    }
    inline void modify(int k,int l,int r,int x){
    	if(l<=s[k].l&&s[k].r<=r){
    		s[k].sqr=(s[k].sqr+2*x*s[k].sum+(s[k].r-s[k].l+1)*x*x)%MOD;
    		s[k].sum=(s[k].sum+(s[k].r-s[k].l+1)*x)%MOD;
    		s[k].lz+=x;
    		return;
    	}
    	pushdown(k);
    	int mid=(s[k].l+s[k].r)>>1;
    	if(r<=mid)		modify(k<<1,l,r,x);
    	else if(l>mid)	modify(k<<1|1,l,r,x);
    	else			modify(k<<1,l,mid,x),modify(k<<1|1,mid+1,r,x);
    	pushup(k);
    }
    inline int query(int k,int l,int r){
    	if(l<=s[k].l&&s[k].r<=r){
    		return s[k].sqr;
    	}
    	pushdown(k);
    	int mid=(s[k].l+s[k].r)>>1;
    	if(r<=mid)		return query(k<<1,l,r);
    	else if(l>mid)	return query(k<<1|1,l,r);
    	else			return (query(k<<1,l,mid)+query(k<<1|1,mid+1,r))%MOD;
    }
    int lst[1000005];
    signed main(){
    	n=read();
    	fz(i,1,n)	a[i]=read();
    	fz(i,1,n)	key[i]=a[i];
    	sort(key+1,key+n+1);
    	fz(i,1,n)	if(key[i]!=key[i-1])	hs[++cnt]=key[i];
    	fz(i,1,n)	a[i]=lower_bound(hs+1,hs+cnt+1,a[i])-hs;
    	fz(i,1,cnt)	lst[i]=n+1;
    	build(1,1,n);
    	int ans=0;
    	fd(i,n,1){
    		modify(1,i,lst[a[i]]-1,1);
    		ans=(ans+query(1,i,n))%MOD;
    //		cout<<query(1,i,n)<<endl;
    		lst[a[i]]=i;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    /*
    6
    1 2 1 3 2 1
    */
    

    T3:
    做题经历:由于做完 T2 之后划了 (40) 分钟的水,时间不太够了。再加上一开始 ix35 神仙还发了个贴说看不懂样例(雾,信就是 ix35 在假,因为他不久就狂切掉了这道题),让我以为是道毒瘤题就没往下写。
    因此花了 (20) 分钟写了个暴力 (40) 分程序就走人了。
    赛后看了下题解发现思路其实也没那么超纲。
    不管怎样赛后再填吧。

    赛后 (30) 分钟心情还是蛮好的。
    然后发现要文操。
    呃呃呃呃呃……什么东西。

    最后,爆零选手 ET2006 衷心提醒大家:
    忘文件操作,爆零两行泪。

  • 相关阅读:
    Linux
    Other
    Linux
    VIM
    Linux
    其他
    Win10
    Win10
    IDE
    其他
  • 原文地址:https://www.cnblogs.com/ET2006/p/12775259.html
Copyright © 2011-2022 走看看