• 雅礼集训2017day10乱写


    t1

    我们假设每个位置被(d[i])个人选择了,并设(s[k]=(sumlimits_{i=1}^{k}d[i])-k)

    找出最小的(k),可以证明如果从(k+1)开始讨论,所有精灵都不用跨过((k,k+1))寻找对手

    然后就是贪心问题了,遍历到一个位置,把将要与其决斗的精灵插入(set)

    然后再(set)中找第一个大于等于当前力量值的精灵

    #include<bits/stdc++.h>
    using namespace std;
    namespace red{
    #define ls(p) (p<<1)
    #define rs(p) (p<<1|1)
    #define mid ((l+r)>>1)
    #define lowbit(i) ((i)&(-i))
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	const int N=5e5+10,inf=0x3f3f3f3f;
    	int n,k,minn,sum,ret;
    	int head[N],cnt;
    	struct point
    	{
    		int nxt,to;
    		point(){}
    		point(const int &nxt,const int &to):nxt(nxt),to(to){}
    	}a[N<<1];
    	int p[N],b[N],c[N],d[N]; 
    	set<int> s;
    	set<int>::iterator it;
    	inline void link(int x,int y)
    	{
    		a[++cnt]=(point){head[x],y};head[x]=cnt;
    	}
    	inline void main()
    	{
    		n=read();minn=inf;
    		for(int i=1;i<=n;++i) p[i]=read(),++d[p[i]],link(p[i],i);
    		for(int i=1;i<=n;++i) b[i]=read();
    		for(int i=1;i<=n;++i) c[i]=read();
    		for(int i=1;i<=n;++i)
    		{
    			sum+=d[i];
    			if(minn>sum-i) minn=sum-i,k=i;
    		}
    		for(int i=1;i<=n;++i)
    		{
    			if(++k>n) k=1;
    			for(int e=head[k];e;e=a[e].nxt)
    			{
    				int t=a[e].to;
    				s.insert(c[t]);
    			}
    			if(b[k]>*--s.end()) s.erase(s.begin());
    			else it=s.lower_bound(b[k]),s.erase(it),++ret;
    		}
    		printf("%d
    ",ret);
    	}
    }
    signed main()
    {
    	red::main();
    	return 0;
    }
    

    t2

    求严格上升子序列,我们可以把整个序列赋值一边翻转然后插在开头

    (4 3 1 2 2 1 3 4)

    求出这个序列的最长严格上升子序列长度和方案数,然后将方案数乘以(2^{n-maxlen-1})

    #include<bits/stdc++.h>
    using namespace std;
    namespace red{
    #define ls(p) (p<<1)
    #define rs(p) (p<<1|1)
    #define mid ((l+r)>>1)
    #define lowbit(i) ((i)&(-i))
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	const int N=5e5+10,mod=1e9+7,inf=0x3f3f3f3f; 
    	int n;
    	int a[N],b[N];
    	int c[N],num;
    	int f[N],g[N],len[N];
    	struct node
    	{
    		int x,y;
    	}ans[N<<2];
    	inline node merge(node a,node b)
    	{
    		if(a.x==b.x) return(node){a.x,(a.y+b.y)%mod};
    		return a.x<b.x?b:a;
    	}
    	inline void update(int pos,int l,int r,int p,node k)
    	{
    		if(l==r)
    		{
    			ans[p]=merge(ans[p],k);
    			return;
    		}
    		if(pos<=mid) update(pos,l,mid,ls(p),k);
    		if(pos>mid) update(pos,mid+1,r,rs(p),k);
    		ans[p]=merge(ans[ls(p)],ans[rs(p)]);
    	}
    	inline node query(int pos,int l,int r,int p)
    	{
    		if(r<=pos) return ans[p];
    		if(mid<pos) return merge(query(pos,l,mid,ls(p)),query(pos,mid+1,r,rs(p)));
    		return query(pos,l,mid,ls(p));
    	}
    	inline void main()
    	{
    		n=read();
    		for(int i=1;i<=n;++i) a[i]=b[i]=read(),c[++num]=a[i];
    		sort(c+1,c+n+1);
    		num=unique(c+1,c+num+1)-c-1;
    		reverse(a+1,a+n+1);
    		for(int i=1;i<=n;++i) a[i+n]=b[i];
    		for(int i=1;i<=n*2;++i)
    		{
    			a[i]=lower_bound(c+1,c+num+1,a[i])-c+1;
    			node t=query(a[i]-1,1,n+1,1);
    			if(t.x==0) t=(node){1,1};
    			else ++t.x;
    			update(a[i],1,n+1,1,t);
    		}
    		node t=query(n+1,1,n+1,1);
    		printf("%d ",t.x);
    		for(int i=1;i<=n-t.x-1;++i) t.y=t.y*2%mod;
    		if(t.x==n) t.y=1;
    		printf("%d ",t.y);
    	}
    }
    signed main()
    {
    	red::main();
    	return 0;
    }
    

    t3

    我们可以把苍蝇拍套在矩阵里,然后枚举左下角就可以枚举到全部位置

    先用(bitset)把哪些位置有苍蝇标记出来,然后把苍蝇拍可以覆盖到的位置标记为(1)

    然后枚举(x)轴和左下角,判断是否会拍到苍蝇

    #include<bits/stdc++.h>
    using namespace std;
    namespace red{
    #define ls(p) (p<<1)
    #define rs(p) (p<<1|1)
    #define mid ((l+r)>>1)
    #define lowbit(i) ((i)&(-i))
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	const int N=510,M=1e5+10,mod=1e9+7,inf=0x3f3f3f3f; 
    	int n,m,k,top,minx=inf,miny=inf,maxx=-inf,maxy=-inf;
    	int ret;
    	struct node
    	{
    		int x,y;
    	}p[M],nfly,a,b;
    	bitset<N> pfly[N],fly[N],now;
    	double st[N];
    	bool ans[N][N];
    	inline void main()
    	{
    		n=read(),m=read(),k=read();
    		for(int i=1;i<=k;++i)
    			nfly.x=read(),nfly.y=read(),fly[nfly.x].set(nfly.y);
    		k=read();
    		for(int i=1;i<=k;++i)
    		{
    			p[i].x=read(),p[i].y=read();
    			minx=min(minx,p[i].x);
    			miny=min(miny,p[i].y);
    			maxx=max(maxx,p[i].x);
    			maxy=max(maxy,p[i].y);
    		}
    		maxx-=minx,maxy-=miny;
    		for(int i=1;i<=k;++i)
    			p[i].x-=minx,p[i].y-=miny,pfly[p[i].x].set(p[i].y);
    		for(int x=0;x<=maxx;++x)//把苍蝇拍的覆盖到的点标记为1 
    		{
    			top=0;
    			for(int i=1;i<=k;++i)
    			{
    				a=p[i],b=p[i==k?1:i+1];
    				if(a.y>b.y) swap(a,b);
    				if((a.x<x&&b.x<x)||(a.x>x&&b.x>x)||(a.x==x&&b.x>x)||(b.x==x&&a.x>x)) continue;
    				if(a.x==x&&b.x==x)
    				{
    					for(int y=a.y+1;y<=b.y-1;++y) pfly[x].set(y);
    					continue;
    				}
    				double k=1.0*(b.y-a.y)/(b.x-a.x);
    				st[++top]=k*(x-a.x)+a.y;
    			}
    			sort(st+1,st+top+1);
    			for(int y=0,flag=0,i=1;y<=maxy;++y)
    			{
    				while(i<=top&&st[i]<y) ++i,flag^=1;
    				if(flag||(i<=top&&st[i]==y)) pfly[x].set(y);
    			}
    		}
    		for(int i=0;i<=maxx;++i)
    		{
    			for(int y=0;y<=m-maxy;++y)
    			{
    				now=pfly[i]<<y;
    				for(int x=0;x<=n-maxx;++x)
    				{
    					if(!ans[x][y]&&(now&fly[x+i]).any())//在哪些点下手会拍到苍蝇 
    						ans[x][y]=1;
    				}
    			}
    		}
    		for(int x=0;x<=n-maxx;++x)
    		{
    			for(int y=0;y<=m-maxy;++y)
    			{
    				ret+=!ans[x][y];
    			}
    		}
    		printf("%d
    ",ret);
    	}
    }
    signed main()
    {
    	red::main();
    	return 0;
    }
    
  • 相关阅读:
    熟悉常用的HDFS操作
    爬虫大作业-爬取B站弹幕
    数据结构化与保存
    使用正则表达式,取得点击次数,函数抽离
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    综合练习:词频统计
    理解MapReduce
    熟悉常用的HBase操作
    熟悉常用的HDFS操作
  • 原文地址:https://www.cnblogs.com/knife-rose/p/12807167.html
Copyright © 2020-2023  润新知