zoukankan      html  css  js  c++  java
  • noip模拟测试34

    这次考试,全靠第一题撑着了,第一题我画了画图,就看出了二分答案,然后差不多半个小时就码的差不多了,又加上了一点小优化,但是没拿到满分,失误有两点,1.二分之前没有特判0的情况 2.这属于一个知识性问题,我当时不知道,因为快排带log,所以我们可以使用一个 nth_element()取出序列前m大。然后是T2,虽然题面看起来像是一个高斯消元,但是结合数据范围,我就知道事情没有辣么简单,高斯消元一次就是n^3, 显然过不去,但是,我当时注意到了每次之需要求出 x1,但是没想到把所有变量都用 x1 表示(我太菜了),最后是T3,我当时一直在想一条直线扫过来扫过去,但是我不知道如何实现,想了半天只能打个暴力,还打假了。这次要没有T1,估计又要保龄了。。。

    T1 Merchant

    思路:画个图,因为每个物品的价值都是一个一次函数,所以显然具有决策单调性,我们可以进行二分答案,但是由于我们需要取出序列前m大,可以使用nth_element() O(N),求出,但是,这东西只能保证将序列前 m 小的东西放在前 m 位,但不保证是有序的,所以在计算过程中我们需要特判,如果小于0就选择不放。
    代码如下:

    AC_code
    #include<bits/stdc++.h>
    #define int long long
    #define re register int
    #define ii inline int
    #define iv inline void
    using namespace std;
    const int N=1e6+10;
    struct node
    {
    	int k,b;
    }use[N];
    int n,m,s;
    ii read()
    {
    	int x=0;
    	bool f=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9')
    	{
    		if(ch=='-')
    			f=0;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9')
    	{
    		x=(x<<1)+(x<<3)+(ch^48);
    		ch=getchar();
    	}
    	return f?x:(-x);
    }
    inline bool check(int x)
    {
    	int cnt=0,sum=0;
    	int q[N];
    	for(re i=1;i<=n;i++)
    		q[i]=((use[i].k*x+use[i].b)*-1);
    	nth_element(q+1,q+m+1,q+n+1);
    	for(re i=1;i<=m;i++)
    	{
    		if(sum>=s)
    			break;
    		if(q[i]<0)
    			sum-=q[i];
    	}
    	return sum>=s;
    }
    ii my(node a,node b)
    {
    	if(a.k!=b.k)
    		return a.k>b.k;
    	return a.b>b.b;
    }
    signed main()
    {
    	n=read();
    	m=read();
    	s=read();
    	bool fu=1,zh=1;
    	for(re i=1;i<=n;i++)
    	{
    		use[i].k=read();
    		use[i].b=read();
    		if(use[i].k>0)
    			fu=0;
    		if(use[i].k<0)
    			zh=0;
    	}
    	sort(use+1,use+n+1,my);	
    	if(check(0))
    	{
    		printf("0\n");
    		return 0;
    	}
    	int l=0,r=1e9+10,out=r,out2=r;
    	while(l<=r)
    	{
    		int mid=(l+r)>>1;
    		if(check(mid))
    		{
    			out=mid;
    			r=mid-1;
    		}
    		else
    			l=mid+1;
    	}
    	printf("%lld\n",out);
    	return 0;
    }
    

    T2 Equation

    思路:看到这种数据范围,显然是nlogn,所以我们考虑使用线段树,显然,我们可以将每个变量表示成 \(x_i=k_i+x_1\)\(x_i=k_i-x_1\) 的形式,那么对于询问 u,v,t ,将表示 u 和 v的式子加起来,只会存在如下几种情况,
    1.\(x_u+x_v=t\),只需要判断等式是否成立.
    2.\(x_u+x_v=t-2\times x_1\)
    3.\(x_u+x_v=t+2\times x_1\)
    那么这就是一个区间修改,单点查询的操作,我们可以使用线段树或者树状数组实现,我使用了线段树,我们在线段树上只需要保存三个东西,自己的权值(sum),两个延迟标记(lazy),由于修改的时候对于深度为奇偶的点影响不同,所以这两个延迟标记数组一个是奇加偶减,另一个是偶加奇减,还要注意在每次 change 的时候都要判断当前的深度奇偶性!!
    代码如下:

    AC_code
    #include<bits/stdc++.h>
    #define re register int
    #define ii inline int
    #define iv inline void
    #define lc (rt<<1)
    #define rc (rt<<1|1)
    #define mid ((l+r)>>1)
    using namespace std;
    const int N=1e6+10;
    int n,q,tot,timi;
    int to[N<<1],next[N<<1],val[N<<1],head[N];
    int size[N],deep[N],id[N],dp[N],zh[N],ifs[N],fw[N];
    ii read()
    {
    	int x=0;
    	bool f=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9')
    	{
    		if(ch=='-')
    			f=0;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9')
    	{
    		x=(x<<1)+(x<<3)+(ch^48);
    		ch=getchar();
    	}
    	return f?x:(-x);
    }
    struct Segment_Tree
    {
    	int sum[N<<2],lazy1[N<<2],lazy2[N<<2];
    	iv updata_1(int p,int l,int r,int w)
    	{
    		if(l==r)
    		{
    			if(deep[ifs[l]])
    				sum[p]+=w;
    			else
    				sum[p]-=w;	
    			return;
    		}
    		lazy1[p]+=w;
    	}
    	iv updata_2(int p,int l,int r,int w)
    	{
    		if(l==r)
    		{
    			if(deep[ifs[l]])
    				sum[p]-=w;
    			else
    				sum[p]+=w;
    			return;
    		}
    		lazy2[p]+=w;
    	}
    	iv pd(int rt,int l,int r)
    	{
    		if(lazy1[rt])
    		{
    			updata_1(lc,l,mid,lazy1[rt]);
    			updata_1(rc,mid+1,r,lazy1[rt]);
    			lazy1[rt]=0;
    		}
    		if(lazy2[rt])
    		{
    			updata_2(lc,l,mid,lazy2[rt]);
    			updata_2(rc,mid+1,r,lazy2[rt]);
    			lazy2[rt]=0;
    		}
    	}
    	iv build(int rt,int l,int r)
    	{
    		if(l==r)
    		{
    			sum[rt]=zh[l];
    			return;
    		}
    		build(lc,l,mid);
    		build(rc,mid+1,r);
    	}
    	inline long long query(int rt,int l,int r,int p)
    	{
    		if(l==r)
    			return sum[rt];
    		pd(rt,l,r);
    		if(mid>=p)
    			return query(lc,l,mid,p);
    		return query(rc,mid+1,r,p);
    	}
    	iv insert_1(int rt,int l,int r,int L,int R,int z)
    	{
    		if(L>R)
    			return;
    		if(L<=l&&r<=R)
    		{
    			if(l==r)
    			{
    				if(deep[ifs[l]])
    					sum[rt]+=z;
    				else
    					sum[rt]-=z;
    				return;
    			}
    			lazy1[rt]+=z;
    			return;
    		}
    		pd(rt,l,r);
    		if(mid>=L)
    			insert_1(lc,l,mid,L,R,z);
    		if(mid<R)
    			insert_1(rc,mid+1,r,L,R,z);
    	}
    	iv insert_2(int rt,int l,int r,int L,int R,int z)
    	{
    		if(L>R)
    			return;
    		if(L<=l&&r<=R)
    		{
    			if(l==r)
    			{
    				if(deep[ifs[l]])
    					sum[rt]-=z;
    				else
    					sum[rt]+=z;
    				return;
    			}
    			lazy2[rt]+=z;
    			return;
    		}
    		pd(rt,l,r);
    		if(mid>=L)
    			insert_2(lc,l,mid,L,R,z);
    		if(mid<R)
    			insert_2(rc,mid+1,r,L,R,z);
    	}
    }T;
    iv add(int x,int y,int w)
    {
    	to[++tot]=y;
    	next[tot]=head[x];
    	head[x]=tot;
    	val[tot]=w;
    }
    iv dfs(int st,int f)
    {
    	deep[st]=deep[f]^1;
    	size[st]=1;
    	id[st]=++timi;
    	ifs[timi]=st;
    	for(re i=head[st];i;i=next[i])
    	{
    		int p=to[i];
    		dfs(p,st);
    		size[st]+=size[p];
    	}
    }
    iv dfs2(int st,int f)
    {
    	for(re i=head[st];i;i=next[i])
    	{
    		int p=to[i];
    		zh[id[p]]=val[i]-zh[id[st]];
    		dfs2(p,st);
    	}
    }
    signed main()
    {
    	n=read();
    	q=read();
    	int f,w,opt,u,v;
    	long long ans1,ans2,s;
    	for(re i=2;i<=n;i++)
    	{
    		f=read();
    		w=read();
    		fw[i]=w;
    		add(f,i,w);
    	}
    	dfs(1,0);
    	dfs2(1,0);
    	T.build(1,1,n);
    	while(q--)
    	{
    		opt=read();
    		if(opt==1)
    		{
    			u=read();
    			v=read();
    			s=read();
    			ans1=T.query(1,1,n,id[u]);
    			ans2=T.query(1,1,n,id[v]);;
    			if(deep[u]!=deep[v])
    			{
    				if(ans1+ans2!=s)
    					printf("none\n");
    				else
    					printf("inf\n");
    			}
    			else
    			{
    				if(deep[u]==0)
    				{
    					if(!((ans1+ans2-s)&1))
    						printf("%d\n",(ans1+ans2-s)/2);
    					else
    						printf("none\n");
    				}
    				else
    				{
    					if(!((s-ans1-ans2)&1))
    						printf("%d\n",(s-ans1-ans2)/2);
    					else
    						printf("none\n");
    				}
    			}
    		}	
    		else
    		{	
    			u=read();
    			w=read();
    			int tmp=w;
    			w=w-fw[u];
    			if(deep[u])
    				T.insert_1(1,1,n,id[u],id[u]+size[u]-1,w);
    			else
    				T.insert_2(1,1,n,id[u],id[u]+size[u]-1,w);
    			fw[u]=tmp;
    		}
    	}	
    	return 0;
    }
    
    
  • 相关阅读:
    JavaWeb--HttpSession案例
    codeforces B. Balls Game 解题报告
    hdu 1711 Number Sequence 解题报告
    codeforces B. Online Meeting 解题报告
    ZOJ 3706 Break Standard Weight 解题报告
    codeforces C. Magic Formulas 解题报告
    codeforces B. Sereja and Mirroring 解题报告
    zoj 1109 Language of FatMouse 解题报告
    hdu 1361.Parencodings 解题报告
    hdu 1004 Let the Balloon Rise 解题报告
  • 原文地址:https://www.cnblogs.com/WindZR/p/15120817.html
Copyright © 2011-2022 走看看