牛客挑战赛34 A~E
闷声发大财
A
O(nmk)dp即可,因为带了1/2的常数+2s所以很稳
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
using namespace std;
int a[801];
int p[801][801];
long long f[801][801];
int n,m,i,j,k,l,K,Y;
int main()
{
//	freopen("a.in","r",stdin);
	scanf("%d%d%d%d",&n,&m,&K,&Y);
	fo(i,1,n)
	scanf("%d",&a[i]);
	fo(i,1,n)
	{
		fo(j,1,m)
		{
			scanf("%d",&p[i][j]);
			if (j<Y)
			p[i][j]+=a[i]*j;
		}
	}
	memset(f,127,sizeof(f));
	f[0][0]=0;
	fo(i,0,n-1)
	{
		fo(j,0,K)
		if (f[i][j]<800000000000ll)
		{
			fd(k,min(K-j,m),0)
			f[i+1][j+k]=min(f[i+1][j+k],f[i][j]+p[i+1][k]);
		}
	}
	printf("%lld\n",f[n][K]);
}
B
m=2的约瑟夫问题,给出一个人求n=1~n时剩下这个人的方案&最大的n
约瑟夫的O(n)递推显然过不了,但是随便打表可以发现答案长这样:
1 1 3 1 3 5 7 1 3 5 7 9 11 13 15 1...
随便算
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
using namespace std;
//int f[233];
long long n,m,s,S,ans1,ans2;
int main()
{
//	freopen("b.in","r",stdin);
	scanf("%lld%lld",&n,&m);
	if (!(m&1))
	{
		printf("0 0\n");
		return 0;
	}
	S=0;s=1;
	while (n)
	{
		if (n>=s)
		{
			n-=s;
			if (m<=s*2-1)
			++ans1,ans2=S+(m+1)/2;
		}
		else
		{
			if (m<=n*2-1)
			++ans1,ans2=S+(m+1)/2;
			n=0;
		}
		S+=s;
		s=s*2;
	}
	printf("%lld %lld\n",ans1,ans2);
	return 0;
//	f[1]=0;
//	fo(i,2,100)
//	f[i]=(f[i-1]+2)%i;
//
//	fo(i,1,100)
//	cout<<f[i]+1<<" ";
//	if (!f[i])
//	cout<<f[i-1]+1<<" ";
}
C
在普通循环同构的基础上加上了对角互换
懒得画
假设有一条直线穿过圆,并且保证直线上方的数<=对应的直线下方的数
这样解决了对角互换的条件
然后将圆旋转,可以发现上下两部分同时旋转了
于是可以把一对对应点看成一个元素,那么变成元素种数为m(m+1)/2,环的大小为n的普通轮换问题
直接O(n)枚举会挂,所以枚举gcd,再乘上phi(n/gcd)即可
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mod 19260817
#define Mod 19260815
using namespace std;
int f[mod+1];
int p[1226565];
int T,i,j,k,l,len,s;
long long n,m,ans;
void init()
{
	int i,j;
	fo(i,1,mod) f[i]=i;
	fo(i,2,mod)
	{
		if (f[i]==i)
		{
			--f[i];
			p[++len]=i;
		}
		fo(j,1,len)
		if ((long long)i*p[j]<=mod)
		{
			if (!(i%p[j]))
			{
				f[i*p[j]]=f[i]*p[j];
				break;
			}
			else
			f[i*p[j]]=f[i]*(p[j]-1);
		}
		else
		break;
	}
}
long long qpower(long long a,int b)
{
	long long ans=1;
	while (b)
	{
		if (b&1)
		ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
int gcd(int n,int m)
{
	int r=n%m;
	while (r)
	{
		n=m;
		m=r;
		r=n%m;
	}
	return m;
}
int main()
{
//	freopen("c.in","r",stdin);
	init();
	scanf("%d",&T);
	for (;T;--T)
	{
		scanf("%lld%lld",&n,&m);
		m=m*(m+1)/2%mod;
		s=floor(sqrt(n));
		ans=0;
		fo(i,1,s)
		if (!(n%i))
		{
			ans=(ans+qpower(m,i)*f[n/i]%mod)%mod;
			if (i*i!=n)
			ans=(ans+qpower(m,n/i)*f[i]%mod)%mod;
		}
//		ans=(ans+qpower(m,gcd(n,i)))%mod;
		ans=ans*qpower(n,Mod)%mod;
		printf("%lld\n",ans);
	}
}
D
sb题
把平面旋转45°再扩大\(\sqrt{2}\)倍(即(x,y)-->(x+y,y-x)),变成D*D的矩形操作
排序+扫描线
注意边界不能减
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define low(x) (x&-(x))
#define N 200001
using namespace std;
struct type{
	int x,y,s;
} a[200001];
int tr[4*N+1];
int tot,n,D,L,i,j,k,l,x,y,sum;
long long ans;
bool cmp(type a,type b)
{
	return a.x<b.x || a.x==b.x && a.s<b.s;
}
void change(int t,int l,int r,int x,int s)
{
	int mid=(l+r)/2;
	tr[t]+=s;
	if (l==r)
	return;
	if (x<=mid)
	change(t*2,l,mid,x,s);
	else
	change(t*2+1,mid+1,r,x,s);
}
int find(int t,int l,int r,int x,int y)
{
	int mid=(l+r)/2,ans=0;
	if (x<=l && r<=y)
	return tr[t];
	if (x<=mid)
	ans+=find(t*2,l,mid,x,y);
	if (mid<y)
	ans+=find(t*2+1,mid+1,r,x,y);
	return ans;
}
int main()
{
//	freopen("d.in","r",stdin);
	scanf("%d%d%d",&n,&D,&L);
	fo(i,1,n)
	{
		scanf("%d%d",&x,&y);
		j=x;k=y;
		x=j+k;
		y=k-j;
		a[++tot]={x,y,1};
		a[++tot]={x+D,y,-1};
	}
	sort(a+1,a+tot+1,cmp);
	fo(i,1,tot)
	{
		if (a[i].s==1)
		{
			ans+=sum-find(1,1,N,max(a[i].y+100001-D+1,1),min(a[i].y+100001+D-1,N));
			++sum;
		}
		change(1,1,N,a[i].y+100001,a[i].s);
	}
	printf("%lld\n",ans);
}
E
用总数-没有交点的即可,删除可以看成加了一个-1的矩形
求出每个询问上下左右的矩形个数,再减去四个角上的
注意时间也算一维(不用排序),所以需要cdq
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define low(x) (x&-(x))
using namespace std;
struct type{
	int x1,y1,x2,y2,s,id;
} a[100001],b[100001];
struct Type{
	int s,id;
} c[200001];
struct type1{
	int x,s,id;
} d[100001];
struct type2{
	int x,y,s,id,Id;
} D[100001];
int tr[200001];
int ans[200001];
int n,i,j,k,l,tp,tot,Tot,sum,len;
bool Cmp(Type a,Type b) {return a.s<b.s;}
bool cmp(type2 a,type2 b) {return a.x<b.x || a.x==b.x && a.id>b.id;}
void change(int t,int s)
{
	while (t<=200000)
	{
		tr[t]+=s;
		t+=low(t);
	}
}
void clear(int t)
{
	while (t<=200000)
	{
		tr[t]=0;
		t+=low(t);
	}
}
int find(int t)
{
	int ans=0;
	while (t)
	{
		ans+=tr[t];
		t-=low(t);
	}
	return ans;
}
void work1()
{
	int i;
	fo(i,1,n)
	if (d[i].s)
	change(d[i].x,d[i].s);
	else
	ans[d[i].id]-=find(d[i].x-1);
	memset(tr,0,sizeof(tr));
}
void work2(int l,int r)
{
	int i,mid=(l+r)/2;
	if (l==r) return;
	work2(l,mid);
	work2(mid+1,r);
	sort(D+l,D+r+1,cmp);
	fo(i,l,r)
	if (D[i].Id<=mid && D[i].s)
	change(D[i].y,D[i].s);
	else
	if (D[i].Id>mid && !D[i].s)
	ans[D[i].id]+=find(D[i].y-1);
	fo(i,l,r)
	if (D[i].Id<=mid && D[i].s)
	clear(D[i].y);
}
int main()
{
//	freopen("e.in","r",stdin);
	scanf("%d",&n);
	fo(i,1,n)
	{
		scanf("%d",&tp);
		switch (tp)
		{
			case 1:{
				scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
				++sum;
				a[i].s=1;
				b[++tot]=a[i];
				break;
			}
			case 2:{
				scanf("%d",&j);
				--sum;
				a[i]=b[j];
				a[i].s=-1;
				break;
			}
			case 3:{
				scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
				a[i].id=++Tot;
				ans[Tot]=sum;
				break;
			}
		}
	}
//	---
	len=0;
	fo(i,1,n)
	{
		c[++len]={a[i].x1,i};
		c[++len]={a[i].x2,-i};
	}
	sort(c+1,c+len+1,Cmp);
	j=0;
	fo(i,1,len)
	{
		j+=i==1 || c[i].s!=c[i-1].s;
		if (c[i].id>0)
		a[c[i].id].x1=j;
		else
		a[-c[i].id].x2=j;
	}
	len=0;
	fo(i,1,n)
	{
		c[++len]={a[i].y1,i};
		c[++len]={a[i].y2,-i};
	}
	sort(c+1,c+len+1,Cmp);
	j=0;
	fo(i,1,len)
	{
		j+=i==1 || c[i].s!=c[i-1].s;
		if (c[i].id>0)
		a[c[i].id].y1=j;
		else
		a[-c[i].id].y2=j;
	}
//	---
	fo(i,1,n)
	if (a[i].s)
	d[i]={a[i].x2,a[i].s,0};
	else
	d[i]={a[i].x1,0,a[i].id};
	work1();
	fo(i,1,n)
	if (a[i].s)
	d[i]={200001-a[i].x1,a[i].s,0};
	else
	d[i]={200001-a[i].x2,0,a[i].id};
	work1();
	fo(i,1,n)
	if (a[i].s)
	d[i]={a[i].y2,a[i].s,0};
	else
	d[i]={a[i].y1,0,a[i].id};
	work1();
	fo(i,1,n)
	if (a[i].s)
	d[i]={200001-a[i].y1,a[i].s,0};
	else
	d[i]={200001-a[i].y2,0,a[i].id};
	work1();
//	---
	fo(i,1,n)
	if (a[i].s)
	D[i]={a[i].x2,a[i].y2,a[i].s,0};
	else
	D[i]={a[i].x1,a[i].y1,0,a[i].id};
	fo(i,1,n)
	D[i].Id=i;
	work2(1,n);
	fo(i,1,n)
	if (a[i].s)
	D[i]={200001-a[i].x1,200001-a[i].y1,a[i].s,0};
	else
	D[i]={200001-a[i].x2,200001-a[i].y2,0,a[i].id};
	fo(i,1,n)
	D[i].Id=i;
	work2(1,n);
	fo(i,1,n)
	if (a[i].s)
	D[i]={a[i].x2,200001-a[i].y1,a[i].s,0};
	else
	D[i]={a[i].x1,200001-a[i].y2,0,a[i].id};
	fo(i,1,n)
	D[i].Id=i;
	work2(1,n);
	fo(i,1,n)
	if (a[i].s)
	D[i]={200001-a[i].x1,a[i].y2,a[i].s,0};
	else
	D[i]={200001-a[i].x2,a[i].y1,0,a[i].id};
	fo(i,1,n)
	D[i].Id=i;
	work2(1,n);
//	---
	fo(i,1,Tot)
	printf("%d\n",ans[i]);
}
牛客挑战赛34 A~E的更多相关文章
- 牛客练习赛34 little w and Segment Coverage (差分区间)
		链接:https://ac.nowcoder.com/acm/contest/297/C来源:牛客网 题目描述 小w有m条线段,编号为1到m. 用这些线段覆盖数轴上的n个点,编号为1到n. 第i条线段 ... 
- 牛客挑战赛 39 牛牛与序列 隔板法 容斥 dp
		LINK:牛牛与序列 (牛客div1的E题怎么这么水... 还没D难. 定义一个序列合法 当且仅当存在一个位置i满足 $a_i>a_,a_j<a_$且对于所有的位置i,$1 \leq a_ ... 
- 牛客挑战赛 30  A 小G数数
		题目链接:https://ac.nowcoder.com/acm/contest/375/A 分析:我写的时候竟然把它当成了DP....... 还建了个结构体DP数组,保存一二位,不知道当时脑子在抽啥 ... 
- 良心送分题(牛客挑战赛35E+虚树+最短路)
		目录 题目链接 题意 思路 代码 题目链接 传送门 题意 给你一棵树,然后把这棵树复制\(k\)次,然后再添加\(m\)条边,然后给你起点和终点,问你起点到终点的最短路. 思路 由于将树复制\(k\) ... 
- Luogu5611 Ynoi2013 D2T2/牛客挑战赛32F 最大子段和 分块、分治
		传送门 之前一直咕着的,因为一些特殊的原因把这道题更掉算了-- 有一个对值域莫队+线段树的做法,复杂度\(O(n\sqrt{n} \log n)\)然而牛客机子实在太慢了没有希望(Luogu上精细实现 ... 
- 牛客挑战赛30 小G砍树 树形dp
		小G砍树 dfs两次, dp出每个点作为最后一个点的方案数. #include<bits/stdc++.h> #define LL long long #define fi first # ... 
- 牛客挑战赛30D 小A的昆特牌(组合数学)
		题面 传送门 题解 很容易写出一个暴力 \[\sum_{i=l}^r {i+n-1\choose n-1}{s-i+m\choose m}\] 即枚举选了多少个步兵,然后用插板法算出方案数 我们对这个 ... 
- 牛客挑战赛30-T3 小G砍树
		link 题目大意: n个节点的带标号无根树.每次选择一个度数为1的节点并将它从树上移除.问总共有多少种不同的方式能将这棵树删到只剩 1 个点.两种方式不同当且仅当至少有一步被删除的节点不同. 题解: ... 
- 【牛客挑战赛30D】小A的昆特牌(组合问题抽象到二维平面)
		点此看题面 大致题意: 有\(S\)张无编号的牌,可以将任意张牌锻造成\(n\)种步兵或\(m\)种弩兵中的一种,求最后步兵数量大于等于\(l\)小于等于\(r\)的方案数. 暴力式子 首先我们来考虑 ... 
随机推荐
- MyView 的无奈问题
			这不是为难我吗这种问题 据说这是内置库!!!!!可是: 找不到呀!!!!!!!!!! 后期补充: 是因为我的一个目录名字起了冲突 
- 01: jenkins简介与安装
			jenkins参考博文:https://www.w3cschool.cn/jenkins/jenkins-173a28n4.html Jenkins中文官网:http://www.jenkins.or ... 
- http://www.pythontutor.com/visualize.html#mode=edit   python在线检测代码
			http://www.pythontutor.com/visualize.html#mode=edit 
- uoj #450[集训队作业2018]复读机
			传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ... 
- CTP报单参数详解
			交易所代码 产品类型 业务类型 价格类型 指令类型 价格类型 OrderPriceType 有效期类型 TimeCondition 成交量类型 VolumeCondition 备注 CZCE 郑商所 ... 
- Ubuntu安装openssh安装ssh、 免密登录、 创建新用户并免密登录
			一.安装openssh sudo apt-get install openssh-server ssh localhost 二.免密登录 cd ~/.ssh ssh-keygen ... 
- ArrayList实现原理分析
			ArrayList使用的存储的数据结构 ArrayList的初始化 ArrayList是如何动态增长 ArrayList如何实现元素的移除 ArrayList小结 ArrayList是我们经常使用的一 ... 
- git和svn 及git使用&解决上线冲突
			一.svn git的工作流程 git 的工作流程图 二.git的基础使用 git 的安装 1.下载对应版本:https://git-scm.com/download 2.安装git:在选取安装路径的下 ... 
- linux上安装Eclipse
			之所以要在linux上安装Eclipse,是因为一开始我是通过Eclipse+MingW+Samba+GDBserver方式在Windows上远程操作,准备编译调试nginx源代码的,可是在编译调试过 ... 
- 怎样减少 Android 应用包 60% 的大小?
			简评: 应用的大小也是用户体验的一个重要方面,而减少 Android 应用安装包大小其实一点也不复杂. 对于移动应用来说,应用安装包的大小当然是越小越好.特别是对于一些欠发达地区,你不希望用户因为手机 ... 
