• NOIP2015


    提高组

    day1

    T1

    纯模拟。

    T2

    Description
    给定一个有向图,求最小的环的大小。
    Solution
    因为每个点的出度都为1,没有自环,所以直接tarjan求每个环的大小即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=200005;
    struct graph{
    	int nxt,to;
    }e[N];
    int g[N],f[N],dfn[N],low[N],sta[N],n,top,ans,cnt;
    bool ins[N];
    void tarjan(int u){
        dfn[u]=low[u]=++cnt;
        sta[++top]=u;ins[u]=true;
        for(int i=g[u];i;i=e[i].nxt)
            if(!dfn[e[i].to]){
                tarjan(e[i].to);
                low[u]=min(low[u],low[e[i].to]);
            }
            else if(ins[e[i].to])
                low[u]=min(low[u],low[e[i].to]);
        if(dfn[u]==low[u]){
        	int tmp=0;
            while(sta[top+1]!=u){
            	++tmp;
                f[sta[top]]=u;
                ins[sta[top--]]=false;
            }
            if(tmp>1) ans=min(ans,tmp);
        }
    }
    void adde(int x,int y){
    	e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1,x;i<=n;++i){
    		scanf("%d",&x);
    		adde(i,x);
    	}
    	ans=n;cnt=0;
        for(int i=1;i<=n;i++)
            if(!dfn[i]) tarjan(i);
        printf("%d",ans);
    	return 0;
    }
    

    day2

    T1

    Description
    从一个数组中删去至多m个数,使\(min\{a_i-a_{i-1}\}\)最大。
    Solution
    二分答案,贪心判定。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=50005;
    int d[N],n,m,l;
    bool chk(int ans){
    	int cnt=0,lst_d=0;
    	for(int i=1;i<=n;++i){
    		if(d[i]-lst_d<ans) ++cnt;
    		else lst_d=d[i];
    	}
    	return cnt<=m;
    }
    int main(){
    	scanf("%d%d%d",&l,&n,&m);
    	for(int i=1;i<=n;++i)
    		scanf("%d",&d[i]);
    	d[++n]=l;
    	int lef=0,rig=l,mid;
    	while(lef<rig){
    		mid=(lef+rig+1)>>1;
    		if(chk(mid)) lef=mid;
    		else rig=mid-1;
    	}
    	printf("%d",lef);
    	return 0;
    }
    

    T2

    Solution

    T3

    Solution

    普及组

    T3

    条件1等价于x+z=2y,即x,z同奇偶。
    问题转化成给定一个大小为\(n_c\)的集,求\(\sum_{x}\sum_{z,x<z}(x+z)\times(number_x+number_z)\).

    \(\begin{aligned}&\sum_{x}\sum_{z,x<z}(x+z)\times(number_x+number_z)\\=&\sum_{x}\sum_{z,x<z}(x\times number_x+z\times number_z+x\times number_z+z\times number_x)\\=&\sum_{x}(n_c-1)(x\times number_x)+\sum_{x}\sum_{z,x\neq z}x\times number_z\\=&\sum_{x}(n_c-1)(x\times number_x)+\sum_{x}x\times \sum_{z,x\neq z}number_z\end{aligned}\)

    预处理后扫一遍可求得。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N=100005,K=10007;
    int c[N],num[N],n,m;
    int c1[N],c2[N];
    ll ans,t1[N],t2[N];
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)
    		scanf("%d",&num[i]);
    	for(int i=1;i<=n;++i)
    		scanf("%d",&c[i]);
    	for(int i=1;i<=n;++i)
    		if(i&1){
    			++c1[c[i]];
    			t1[c[i]]+=num[i];
    		}
    		else{
    			++c2[c[i]];
    			t2[c[i]]+=num[i];
    		}
    	
    	for(int i=1;i<=m;++i){
    		c1[i]%=K;c2[i]%=K;
    	}
    	
    	for(int i=1;i<=n;++i)
    		if(i&1){
    			ans+=1ll*i*num[i]%K*(c1[c[i]]-1)%K;
    			ans%=K;
    		}
    		else{
    			ans+=1ll*i*num[i]%K*(c2[c[i]]-1)%K;
    			ans%=K;
    		}
    	for(int i=1;i<=n;++i)
    		if(i&1){
    			ans+=1ll*i*(t1[c[i]]-num[i])%K;
    			ans%=K;
    		}
    		else{
    			ans+=1ll*i*(t2[c[i]]-num[i])%K;
    			ans%=K;
    		}
    	printf("%lld\n",ans);
    	return 0;
    } 
    

    T4

    用线段树贪心即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=100005,M=400005;
    struct segmentTree{
    	int ma,mw,ia,iw;
    }lt[M]; 
    int a[N],s[N],n,max_s,ans;
    void build(int u,int l,int r){
    	if(l==r){
    		lt[u].ma=a[l];
    		lt[u].mw=a[l]+s[l]*2;
    		lt[u].ia=lt[u].iw=l;
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(u<<1,l,mid);
    	build(u<<1|1,mid+1,r);
    	if(lt[u<<1].ma>lt[u<<1|1].ma){
    		lt[u].ma=lt[u<<1].ma;
    		lt[u].ia=lt[u<<1].ia;
    	}
    	else{
    		lt[u].ma=lt[u<<1|1].ma;
    		lt[u].ia=lt[u<<1|1].ia;
    	}
    	if(lt[u<<1].mw>lt[u<<1|1].mw){
    		lt[u].mw=lt[u<<1].mw;
    		lt[u].iw=lt[u<<1].iw;
    	}
    	else{
    		lt[u].mw=lt[u<<1|1].mw;
    		lt[u].iw=lt[u<<1|1].iw;
    	}
    }
    int ask(int u,int l,int r,int &i){
    	if(l==r){
    		i=l;
    		if(s[l]<=max_s) return lt[u].ma;
    		return lt[u].mw-max_s*2;
    	}
    	if(s[l]>=max_s){
    		i=lt[u].iw;
    		return lt[u].mw-max_s*2;
    	}
    	if(s[r]<=max_s){
    		i=lt[u].ia;
    		return lt[u].ma;
    	}
    	int mid=(l+r)>>1;
    	if(s[mid+1]>=max_s){
    		int ret_l=ask(u<<1,l,mid,i);
    		int ret_r=lt[u<<1|1].mw-max_s*2;
    		if(ret_l>ret_r) return ret_l;
    		i=lt[u<<1|1].iw;
    		return ret_r;
    	}
    	int ret_l=lt[u<<1].ma;
    	int ret_r=ask(u<<1|1,mid+1,r,i);
    	if(ret_l>ret_r){
    		i=lt[u<<1].ia;
    		return ret_l;
    	}
    	return ret_r;
    
    }
    void remove(int u,int l,int r,int i){
    	if(l==r){
    		lt[u].ma=0;lt[u].mw=0;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(i<=mid) remove(u<<1,l,mid,i);
    	else remove(u<<1|1,mid+1,r,i);
    	
    	if(lt[u<<1].ma>lt[u<<1|1].ma){
    		lt[u].ma=lt[u<<1].ma;
    		lt[u].ia=lt[u<<1].ia;
    	}
    	else{
    		lt[u].ma=lt[u<<1|1].ma;
    		lt[u].ia=lt[u<<1|1].ia;
    	}
    	if(lt[u<<1].mw>lt[u<<1|1].mw){
    		lt[u].mw=lt[u<<1].mw;
    		lt[u].iw=lt[u<<1].iw;
    	}
    	else{
    		lt[u].mw=lt[u<<1|1].mw;
    		lt[u].iw=lt[u<<1|1].iw;
    	}
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)
    		scanf("%d",&s[i]);
    	for(int i=1;i<=n;++i)
    		scanf("%d",&a[i]);
    	build(1,1,n);
    	int ans_i;
    	for(int i=1;i<=n;++i){
    		ans+=ask(1,1,n,ans_i);
    		max_s=max(max_s,s[ans_i]);
    		remove(1,1,n,ans_i);
    		printf("%d\n",ans);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    小白的源码阅读之旅_RazorEngine_起因
    Sqlserver_小工具_Json解析
    Sqlserver_小工具_批量字段约束处理
    SqlServer_小工具_获取数据库空间信息获取
    SqlServer_小工具_系统表的使用
    Sqlserver_小工具_字符统计(区分大小写)
    SqlServer_小工具_存储空间单位自适应
    不断优化,重构我的代码-----拖拽jquery插件
    canvas绘制二次贝塞尔曲线----演示二次贝塞尔四个参数的作用
    requestAnimationFrame与setInterval,setTimeout
  • 原文地址:https://www.cnblogs.com/AireenYe/p/NOIP2015.html
Copyright © 2020-2023  润新知