zoukankan      html  css  js  c++  java
  • APIO2016


    2018.5.3 Test

    得分:9+8+100=117

    昨天刚看过T3。。

    T1

    题目链接

    离散化区间后好像很好想到(O(n^2))?调不出来算了。。
    做不下去 先不改了

    
    

    T2

    题目链接

    也不想改。再说。。

    
    

    T3 UOJ.206.[APIO2016]Gap(交互)

    题目链接

    T=1 容易看出是每次要确定两个数。然后就是这样了。
    T=2 调用函数覆盖的数尽量少。
    一次n+1的调用可以找出所有数所在的区间,这个区间中有n-2个数把它分成n-1份。(我也不知道该怎么说了 反正就是这样)
    所以 $ Ansgeq ceil((r-l)/(n-1)) $。(鸽巢原理)
    以这个为区间大小查询,就可以确定出可能产生答案的A[]了。

    #include "gap.h"
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    typedef long long LL;
    const int N=1e5+5;
    const LL INF=1e18;
    
    LL A[N<<1];
    
    long long findGap(int T, int N)
    {
    	LL l=0,r=INF,mn,mx;
    	int h=1,t=N;
    	if(T==1)
    	{
    		for(; h<=t; )
    		{
    			MinMax(l,r,&mn,&mx);
    			A[h++]=mn, A[t--]=mx;
    			l=mn+1, r=mx-1;
    		}
    	}
    	else
    	{
    		MinMax(l,r,&mn,&mx);
    		LL delta=ceil(1.0*(mx-mn+1)/(N-1)),Max=mx;
    		A[h++]=mn;
    		l=mn+1, r=mn+delta;
    		for(; l<r; l=r+1, r=std::min(r+delta,Max))
    		{
    			MinMax(l,r,&mn,&mx);
    			if(mn==-1) continue;
    			A[h++]=mn, A[h++]=mx;
    		}
    		A[h++]=Max, N=h-1;
    	}
    	long long res=0;
    	for(int i=1; i<N; ++i) res=std::max(res,A[i+1]-A[i]);
    	return res;
    }
    

    考试代码

    T1

    #include <map>
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    #define mod (1000000007)
    #define ADD(x,v) (x)+=(v),x>=mod?x-=mod:0
    const int N=505;
    
    int n,A[N],B[N],f[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    namespace Spec1
    {
    	int f[N];
    
    	void Solve()
    	{
    		f[0]=1;
    		for(int i=1; i<=n; ++i)
    			for(int j=0; j<i ;++j)
    				if(A[i]>A[j]) ADD(f[i],f[j]);
    		long long ans=0;
    		for(int i=1; i<=n; ++i) ans+=f[i];
    //		for(int i=1; i<=n; ++i) printf("%d:%d
    ",i,f[i]);
    		printf("%d",int(ans%mod));
    	}
    }
    namespace Spec2
    {
    //	int f[2][1000005];
    	std::map<int,int> f[2];
    
    	void Solve()
    	{
    		int now=0,las=1;
    		f[las][0]=1;
    		long long ans=0,sum;
    		for(int i=1; i<=n; ++i)
    		{
    			sum=0;
    			for(int j=0; j<A[i]; ++j) sum+=f[las][j], f[now][j]=f[las][j];
    			sum%=mod;
    			for(int j=A[i]; j<=B[i]; ++j) f[now][j]=sum, ADD(sum,f[las][j]), ans+=f[now][j];
    			now^=1, las^=1;
    		}
    		printf("%d",int(ans%mod));
    	}
    }
    
    int main()
    {
    	freopen("1.in","r",stdin);
    
    	n=read();
    	for(int i=1; i<=n; ++i) A[i]=read(),B[i]=read();
    	bool f=1;
    	for(int i=1; i<=n; ++i) if(A[i]!=B[i]) {f=0; break;}
    	if(f) {Spec1::Solve(); return 0;}
    	long long sum=0;
    	for(int i=1; i<=n; ++i) sum+=B[i]-A[i];
    	if(sum<=1000000) {Spec2::Solve(); return 0;}
    
    	return 0;
    }
    

    T2

    #include <cmath>
    #include <cstdio>
    #include <cctype>
    #include <vector>
    #include <algorithm>
    #define gc() getchar()
    #define vt std::vector<N>
    const int N=3e5+5,M=6e5+5;
    
    int n,m,Enum,H[N],to[M],nxt[M],len[M];
    long long Max,dep[N],f[N];
    std::vector<int> v[N],tmp;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline void AddEdge(int u,int v,int w){
    	to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, len[Enum]=w;
    	to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, len[Enum]=w;
    }
    namespace Spec1
    {
    	double Calc(double x)
    	{
    		double res=0;
    		for(int i=H[1]; i; i=nxt[i])
    			res+=fabs((double)len[i]-x);
    		return res;
    	}
    	void Solve()
    	{
    		std::sort(len+1,len+1+Enum);
    		printf("%lld",(long long)Calc(len[Enum>>1])); return;
    
    		double l=0,r=Max,lmid,rmid;
    		while(r>l+0.01)
    		{
    			lmid=l+(r-l)/3, rmid=r-(r-l)/3;
    			if(Calc(lmid)>Calc(rmid)) l=lmid;
    			else r=rmid;
    		}
    		printf("%lld",(long long)Calc((int)(l+0.5)));//long long!
    	}
    }
    void Get_dep(int x,int f,int d)
    {
    	dep[x]=d;//this...
    	for(int i=H[x]; i; i=nxt[i])
    		if(to[i]!=f) Get_dep(to[i],x,d+len[i]);	
    }
    void Merge(int i,int j)
    {
    	tmp.clear();
    	int p1=0,l1=v[i].size(),p2=0,l2=v[j].size();
    //	printf("Merge(%d,%d):%d %d
    ",i,j,l1,l2);
    	while(p1<l1 && p2<l2)
    		if(v[i][p1]<=v[j][p2]) tmp.push_back(v[i][p1++]);
    		else tmp.push_back(v[j][p2++]);
    	while(p1<l1) tmp.push_back(v[i][p1++]);
    	while(p2<l2) tmp.push_back(v[j][p2++]);
    	v[i]=tmp;
    }
    void DFS(int x,int fa,int pur)
    {
    	if(x>n) {f[x]=std::abs(dep[x]-pur), v[x].push_back(dep[x]-pur); return;}
    	long long sum=0;
    	for(int t,i=H[x]; i; i=nxt[i])
    		if((t=to[i])!=fa)
    		{
    			DFS(t,x,pur), sum+=f[t], Merge(x,t);
    //			printf("son:f[%d]:%lld sum:%lld
    ",t,f[t],sum);
    		}
    	long long val=v[x][v[x].size()-1>>1];
    //	printf("%d(%d,%d):
    ",x,p,v[x][p]);
    //	for(int i=0; i<v[x].size(); ++i) printf("%d ",v[x][i]);putchar('
    ');
    	f[x]=std::abs(val);
    	for(int i=0; i<v[x].size(); ++i) f[x]+=std::abs(val-v[x][i]);
    //	printf("f[%d]:%lld sum:%lld
    ",x,f[x],sum);
    	f[x]=std::min(f[x],sum);
    }
    double Calc(double x)
    {
    	DFS(1,1,x);
    	return f[1];
    }
    void Spec()
    {
    	long long res=1e16;
    	for(int i=0; i<=Max; ++i){
    		for(int j=1; j<=n+m; ++j) v[j].clear();
    		DFS(1,1,i),res=std::min(res,f[1]);	
    	}
    	printf("%lld",res);
    }
    
    int main()
    {
    	freopen("2.in","r",stdin);
    
    	n=read(),m=read();
    	for(int u,i=2; i<=n+m; ++i) u=read(),AddEdge(u,i,read());
    	Get_dep(1,1,0);
    	for(int i=1; i<=n+m; ++i) Max=std::max(Max,dep[i]);
    	if(n==1) {Spec1::Solve(); return 0;}
    
    	Spec(); return 0;
    
    	double l=0,r=Max,lmid,rmid;
    	while(r>l+0.01)
    	{
    		lmid=l+(r-l)/3, rmid=r-(r-l)/3;
    		printf("%.3lf,%.3lf->",l,r);
    		if(Calc(lmid)>Calc(rmid)) l=lmid;
    		else r=rmid;
    		printf("%.3lf %.3lf
    ",l,r);
    	}
    	printf("%d %lld
    ",(int)(l+0.5),Max);
    	printf("%lld",(long long)Calc((int)(l+0.5)));//long long!
    
    	return 0;
    }
    
  • 相关阅读:
    C#学习第四弹之封装、继承和多态
    C#学习第三弹之给常量赋值可能引发的问题
    C#学习第二弹之C#与.NET框架
    hdu 5199 map或二分或哈希
    hdu 5195 线段树
    hdu 2545 并查集
    ACM数论模板
    C#学习第一弹之Hello World
    对字符串进行频繁拼接的话,使用StringBuffer或者StringBuilder
    String中根据,(逗号)进行分割
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8986604.html
Copyright © 2011-2022 走看看