zoukankan      html  css  js  c++  java
  • 8.4 正睿暑期集训营 Day1


    2018.8.4 正睿暑期集训营 Day1

    时间:4.5h(实际)
    期望得分:30+50+30
    实际得分:30+50+30(菜啊)

    比赛链接

    A 数对子

    题目链接
    (Solution)
      考虑两个数异或怎么会得到1:(0oplus0=0,0oplus1=1,1oplus1=0),也就是同一位的两个1会抵消成0。那么令(bit[x])表示(x)的二进制1的个数,如果计算奇偶性,(bit[xoplus y]\%2=(bit[x]+bit[y])\%2)。因为如果有变成0的1也一定是两个一起变成0。那么如果令(p_0)表示区间([l,r])(bit[i])为偶数的(i)的个数,(p_1)表示区间中(bit[i])为奇数的(i)的个数,该区间的答案为(p_0 imes p_1)
      计算(p_0),可以数位DP。(p_0[l,r]=p_0[r]-p_0[l-1]),考虑([0,m])中的(p_0)怎么求。对于一个偶数(x)(bit[x])一定与(bit[x+1])奇偶性相反。于是我们这样分组:(01,23,45ldots)奇偶性是这样的:(偶奇,奇偶,奇偶,偶奇ldots)可得:$$p_0[0,m]=egin{cases}frac{m+1}{2},& m为奇数\frac{m}{2}+left[bit[m]是奇数 ight],& m为偶数end{cases}$$
      对于区间的处理,(O(n^2)):把端点离散化,这样把所有区间分成了若干段小区间,每段区间是若干段小区间的并。这样每有一段区间,直接去找属于它的区间即可。如图:
      (O(nlog n)):建一棵值域(1sim2^{32}-1)的线段树,动态开点(能覆盖大区间就直接覆盖,否则递归新建左/右区间节点)。

      root没初始化为0,本地大样例都可过。。OJ上RE,调了很长时间。。(我干什么都RE有时候还能正常输出我也很无奈啊)

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 400000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=100005*17;
    
    char IN[MAXIN],*SS=IN,*TT=IN;
    struct Segment_Tree
    {
    	#define lson son[x][0]
    	#define rson son[x][1]
    	int tot,son[N][2];
    	LL sum[N][2];
    	bool cover[N];
    
    	#define Query(l,r) (Calc(r)-Calc(l-1))
    	#define Update(x) sum[x][0]=sum[lson][0]+sum[rson][0], sum[x][1]=sum[lson][1]+sum[rson][1]
    	inline bool Check(LL x)
    	{
    		int res=0;
    		for(; x; x>>=1) res+=x&1;
    		return res&1;
    	}
    	inline LL Calc(LL x)
    	{
    		return (x>>1)+((x&1)||Check(x));//x&1?(x+1)>>1:(x>>1)+Check(x);
    	}
    	void Insert(int &x,LL l,LL r,LL L,LL R)
    	{
    		if(!x) x=++tot;
    		if(cover[x]) return;
    		if(L<=l && r<=R)
    		{
    			cover[x]=1;
    			sum[x][1]=Query(l,r), sum[x][0]=r-l+1-sum[x][1];
    			return;
    		}
    		LL m=l+r>>1;
    		if(L<=m) Insert(lson,l,m,L,R);
    		if(m<R) Insert(rson,m+1,r,L,R);
    		Update(x);
    		cover[x]=cover[x]||(cover[lson]&&cover[rson]);//!
    	}
    }T;
    
    inline LL read()
    {
    	LL now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    
    int main()
    {
    	int n=read(),root=0;//root初始化为0!!!
    	for(LL l,lim=(1ll<<32)-1; n--; )
    		l=read(), T.Insert(root,1,lim,l,read()), printf("%lld
    ",T.sum[root][0]*T.sum[root][1]);
    
    	return 0;
    }
    

    B 逆序对

    题目链接

    容易看出决策位置单调。可靠这个分治。
    但是有很简单的堆的贪心写法,没看懂。。

    
    

    C 盖房子

    题目链接

    
    

    考试代码

    A

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define gc() getchar()
    typedef long long LL;
    typedef unsigned int uint;
    const int N=1e5+5;
    
    int n,A[N];
    uint L[N],R[N];
    bool vis[1003];
    
    inline uint read()
    {
    	uint now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline bool Check(uint x)
    {
    	int res=0;
    	for(; x; x>>=1) res+=x&1;
    	return res&1;
    }
    //void Make()
    //{
    //	int n=read();
    //	for(int i=2; i<=n; ++i)
    //		for(int j=i+1; j<=3*n; ++j) if(Check(i^j)) printf("%d^%d=%d is OK
    ",i,j,i^j);
    //}
    
    int main()
    {
    //	freopen(".in","r",stdin);
    
    //	Make();
    	n=read();
    	for(uint i=1,li,ri; i<=n; ++i)
    	{
    		li=L[i]=read(), ri=R[i]=read();
    
    		memset(vis,0,sizeof vis);
    		int cnt=0;
    		for(int j=1; j<i; ++j)
    			for(uint k=L[j],r=R[j]; k<=r; ++k)
    				if(!vis[k]) A[++cnt]=k, vis[k]=1;
    		for(uint j=li; j<=ri; ++j)
    			if(!vis[j]) A[++cnt]=j, vis[j]=1;
    
    		LL ans=0;
    		for(int j=1; j<cnt; ++j)
    			for(int k=j+1; k<=cnt; ++k)
    				ans+=Check(A[j]^A[k]);
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    B

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 400000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    #define Vec std::vector<int>
    typedef long long LL;
    const int N=2e5+5;
    
    int n,cnt,B[N];
    LL Ans;
    char IN[MAXIN],*SS=IN,*TT=IN;
    struct BIT
    {
    	#define lb(x) (x&-x)
    	int n,val[N];
    	inline void Clear()
    	{
    		memset(val,0,sizeof val);
    	}
    	inline void Add(int p,int v)
    	{
    		if(!p) return;
    		for(; p<=n; p+=lb(p)) val[p]+=v;
    	}
    	inline LL Query(int p)
    	{
    		LL res=0;
    		for(; p; p^=lb(p)) res+=val[p];
    		return res;
    	}
    }T1,T2;
    
    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 LL Query(int p,int v)
    {
    	return p-T1.Query(v)+T2.Query(v);
    }
    inline int Check(int p,int x)
    {
    	LL r1=Query(p,x),r2=r1;
    	int res=p,bef=p;
    	while(p<cnt)
    	{
    		++p;
    		if(B[p]<x) --r2;
    		else if(B[p]>x) ++r2;
    		if(r2<r1) r1=r2, res=p;
    	}
    	for(int i=bef+1; i<=res; ++i) T1.Add(B[i],1), T2.Add(B[i],-1);
    	return Ans+=r1, res;
    }
    inline int Check2(int p,int x,int lim)
    {
    	LL r1=Query(p,x),r2=r1;
    	int res=p,bef=p;
    	while(p<lim)
    	{
    		++p;
    		if(B[p]<x) --r2;
    		else if(B[p]>x) ++r2;
    		if(r2<r1) r1=r2, res=p;
    	}
    	for(int i=bef+1; i<=res; ++i) T1.Add(B[i],1), T2.Add(B[i],-1);
    	return Ans+=r1, res;
    }
    
    int main()
    {
    //	freopen("B2.in","r",stdin);
    
    	T1.n=T2.n=n=read(), cnt=n>>1;
    	for(int i=1; i<=cnt; ++i) T2.Add(B[i]=read(),1);
    	for(int i=1; i<=cnt; ++i) Ans+=i-1-T1.Query(B[i]), T1.Add(B[i],1);
    	T1.Clear();
    	if(n<=5000)
    		for(int i=1,p=0; i<n; i+=2) p=Check(p,i);
    	else
    		for(int i=1,p=0,len=15000000/n; i<n; i+=2) p=Check2(p,i,std::min(i+len,cnt));
    	printf("%lld
    ",Ans);
    
    	return 0;
    }
    

    C

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define gc() getchar()
    #define mod (10007)
    #define Mod(x) (x>=mod&&(x-=mod))
    const int N=36;
    
    int n,K,X[N],Y[N];
    bool ban[N][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 Subtask1
    {
    	int A[N];
    	inline bool Ck1(int *a)
    	{
    		for(int i=1; i<=n; ++i) if(a[i]==i) return 1;
    		return 0;
    	}
    	inline bool Ck2(int *a)
    	{
    		for(int i=1; i<=n; ++i) if(a[i]==n-i+1) return 1;
    		return 0;
    	}
    	inline int Check(int *a)
    	{
    		for(int i=1; i<=n; ++i) if(ban[i][a[i]]) return 0;
    		if(!Ck1(a)) return 0;
    		if(!Ck2(a)) return 0;
    		return 1;
    	}
    	inline bool End(int *a)
    	{
    		for(int i=1; i<=n; ++i) if(a[i]!=i) return 0;
    		return 1;
    	}
    	void Main()
    	{
    		for(int i=1; i<=n; ++i) A[i]=i;
    		int res=0;
    		do{
    			res+=Check(A), std::next_permutation(A+1,A+1+n);
    		}while(!End(A));
    		printf("%d
    ",res%mod);
    	}
    }
    namespace Subtask2
    {
    	int Ans,fac[N];
    	bool vis[N];
    	void DFS(int x,int n,bool f1,bool f2)
    	{
    		if(x>n) {Ans+=(f1&&f2); return;}
    		if(f1&&f2) {Ans+=fac[n-x+1], Ans>=mod&&(Ans-=mod); return;}
    		for(int i=1; i<=n; ++i)
    			if(!vis[i]) vis[i]=1, DFS(x+1,n,f1||(x==i),f2||(x+i==n+1)), vis[i]=0;
    	}
    	void Main()
    	{
    		fac[0]=1;
    		for(int i=1; i<=n; ++i)
    		{
    			fac[i]=fac[i-1]*i;
    			while(fac[i]>=mod) fac[i]-=mod;
    		}
    		DFS(1,n,0,0);
    		printf("%d
    ",Ans%mod);
    	}
    }
    namespace Subtask3
    {
    	int f[2][(1<<18)+3][2][2];
    	void Main()
    	{
    		int lim=(1<<n)-1, now=1, las=0;
    		f[0][0][0][0]=1;
    		for(int i=0; i<n; ++i)
    		{
    			for(int s=0; s<=lim; ++s)
    			{
    				for(int j=0,ss; j<n; ++j)
    				{
    					if(s>>j&1) continue;
    					if(ban[i+1][j+1]) continue;
    					ss=s|(1<<j);
    					f[now][ss][i==j][i+j==n-1]+=f[las][s][0][0], Mod(f[now][ss][i==j][i+j==n-1]);
    					f[now][ss][i==j][1]+=f[las][s][0][1], Mod(f[now][ss][i==j][1]);
    					f[now][ss][1][i+j==n-1]+=f[las][s][1][0], Mod(f[now][ss][1][i+j==n-1]);
    					f[now][ss][1][1]+=f[las][s][1][1], Mod(f[now][ss][1][1]);
    				}
    			}
    			now^=1, las^=1;
    		}
    		printf("%d
    ",f[las][lim][1][1]);
    	}
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    
    	n=read(), K=read();
    	for(int i=1; i<=K; ++i) ban[X[i]=read()][Y[i]=read()]=1;
    	if(n<=10 && !K) return Subtask2::Main(),0;
    	if(n<=10) return Subtask1::Main(),0;
    	if(n<=18) return Subtask3::Main(),0;
    	if(!K && n<=25)
    	{
    		if(n==19) printf("4551
    ");
    		else if(n==20) printf("7535
    ");
    		else if(n==21) printf("5570
    ");
    		else if(n==22) printf("2328
    ");
    		else if(n==23) printf("4809
    ");
    		else if(n==24) printf("8690
    ");
    		else if(n==25) printf("5330
    ");
    //		else if(n==26) printf("
    ");
    //		else if(n==27) printf("
    ");
    //		else if(n==28) printf("
    ");
    	}
    	else putchar('0');
    
    	return 0;
    }
    
  • 相关阅读:
    Chrome触发唤起IE, 注册唤起程序
    .net post请求过长 , 超过配置 maxQueryStringLength值
    eclipse 初探踩坑实录
    eslint 报error
    前端3小时配置空白机环境
    sql语句
    maven3.04管理jetty9.2.10启动web项目
    Oracle日期时间
    AngularJS向指令传递数据
    jetty和tomcat启动项目
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9420192.html
Copyright © 2011-2022 走看看