2018-2019 ICPC, NEERC, Southern Subregional Contest
2018-2019 ICPC, NEERC, Southern Subregional Contest 
(Codeforces 1070)
VP了一场最近的没做过的ACM。ACM的Online Mirror好少啊...
B题看不懂样例=-= K题签到题。其它题咕咕了。
A.Find a Number(BFS)
先要想到令\(f[i][j]\)表示模\(d\)余数为\(i\),数位和为\(j\)的最小数。状态数是OK的。
然后每次转移就是在后面加上\(0\sim 9\)这些数字,用BFS转移就可以保证当前数最小了。复杂度\(O(10ds)\)。
当然还有其它奇奇怪怪的DP方法。
//124ms	32100KB
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define pc putchar
#define gc() getchar()
typedef long long LL;
const int N=503,M=5003;
bool vis[N][M];
struct Node
{
	int r,sum;
};
struct Path
{
	int r,sum;
	char c;
}pre[N][M];
void BFS(const int d,const int s)
{
	std::queue<Node> q;
	q.push((Node){0,0}), vis[0][0]=1;
	while(!q.empty())
	{
		Node x=q.front(); q.pop();
		if(!x.r && x.sum==s) return;
		for(int i=0; i<10; ++i)
		{
			int r=(x.r*10+i)%d, sum=x.sum+i;
			if(sum<=s && !vis[r][sum])
				pre[r][sum]=(Path){x.r,x.sum,char(i+48)}, vis[r][sum]=1, q.push((Node){r,sum});
		}
	}
}
void Output(int d,int s)
{
	if(pre[d][s].c) Output(pre[d][s].r,pre[d][s].sum), pc(pre[d][s].c);
}
int main()
{
	int d,s; scanf("%d%d",&d,&s);
	BFS(d,s);
	if(vis[0][s]) Output(0,s);
	else puts("-1");
	return 0;
}
C.Cloud Computing(线段树)
我写的比较无脑... 按天数为下标建线段树。将物品区间按价格排序,考虑依次加到线段树对应区间上。
设当前区间剩余所需个数的最小值是\(mn\)(初始都为\(k\)),当前物品区间、个数、单位价格分别是\((l,r,a,cost)\)。\(mn\gt a\)时,直接区间减\(a\)统计一下答案就行了;当\(mn\leq a\)时,一定至少有一个位置会被减成\(0\),暴力在线段树找到那个/那些位置把\(size\)清零,\(mn\)设为\(INF\),统计一下答案即可。
因为每个数只会被清空一次,也就是只会暴力做\(O(n)\)次,所以复杂度\(O((n+m)\log n)\)。
其实只要拿价格建一棵值域线段树,每个位置维护有多少个物品就行了。查询就是在树上二分出前\(k\)小的和(树状数组也行)。
//327ms	78600KB
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define pc putchar
#define gc() getchar()
#define MAXIN 500000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e6+5;
const LL INF=3e18;
char IN[MAXIN],*SS=IN,*TT=IN;
struct Node
{
	int l,r,num,cost;
	bool operator <(const Node &x)const
	{
		return cost<x.cost;
	}
}A[N];
struct Segment_Tree
{
	#define ls rt<<1
	#define rs rt<<1|1
	#define lson l,m,ls
	#define rson m+1,r,rs
	#define S N<<2
	LL mn[S];//mn[rt]=INF要足够大!
	int sz[S],tag[S];
	LL Ans;
	#undef S
	#define Upd(rt,v) mn[rt]+=v, tag[rt]+=v
	#define Update(rt) mn[rt]=std::min(mn[ls],mn[rs]), sz[rt]=sz[ls]+sz[rs]
	inline void PushDown(int rt)
	{
		Upd(ls,tag[rt]), Upd(rs,tag[rt]), tag[rt]=0;
	}
	void Build(int l,int r,int rt,int K)
	{
		mn[rt]=K, sz[rt]=r-l+1;
		if(l==r) return;
		int m=l+r>>1; Build(lson,K), Build(rson,K);
	}
	void Modify2(int l,int r,int rt,int a,int cost)
	{
		if(mn[rt]>a) {Ans+=1ll*cost*a*sz[rt], Upd(rt,-a); return;}
		if(l==r) {Ans+=1ll*cost*mn[rt], sz[rt]=0, mn[rt]=INF; return;}
		if(tag[rt]) PushDown(rt);
		int m=l+r>>1;
		Modify2(lson,a,cost), Modify2(rson,a,cost), Update(rt);
	}
	void Modify(int l,int r,int rt,int L,int R,int a,int cost)
	{
		if(L<=l && r<=R) {Modify2(l,r,rt,a,cost); return;}
		if(tag[rt]) PushDown(rt);
		int m=l+r>>1;
		if(L<=m) Modify(lson,L,R,a,cost);
		if(m<R) Modify(rson,L,R,a,cost);
		Update(rt);
	}
}T;
inline int read()
{
	int now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now;
}
int main()
{
	#define S 1,n,1
	const int n=read(),K=read(),m=read();
	for(int i=1; i<=m; ++i) A[i]=(Node){read(),read(),read(),read()};
	std::sort(A+1,A+1+m), T.Build(S,K);
	for(int i=1; i<=m; ++i) T.Modify(S,A[i].l,A[i].r,A[i].num,A[i].cost);
	printf("%I64d\n",T.Ans);
	return 0;
}
D.Garbage Disposal(模拟)
模拟一下就行了。
因为刚开始读错题还写了个二分=v=
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define pc putchar
#define gc() getchar()
typedef long long LL;
const int N=2e5+5;
int A[N];
inline int read()
{
	int now=0,f=1;register char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}
bool Check(LL x,int n,int K)
{
	LL las=0;
	for(int i=1; i<=n; ++i)
	{
		LL need=(las+K-1)/K; las=std::max(0ll,A[i]-(need*K-las));
		x-=need;
		if(x<0) return 0;
	}
	return x>=(las+K-1)/K;//不要写x*K!!!
}
signed main()
{
	int n=read(),K=read(); LL sum=0;
	for(int i=1; i<=n; ++i) sum+=A[i]=read();
	LL l=0,r=3e18,mid,ans=r;
	while(l<=r)
		if(Check(mid=l+r>>1,n,K)) ans=mid, r=mid-1;
		else l=mid+1;
	printf("%I64d\n",ans);
	return 0;
}
E.Getting Deals Done(二分)
显然答案是可以三分的。但是答案是整数三分有点麻烦。
考虑能不能二分一个答案\(mid\)是否可行。如果至少选\(mid\)个,那么要选的肯定是最便宜的\(mid\)个物品。那么模拟一下就行了。
//46ms	2200KB(离散化的版本,那个写的太丑了留这个代码叭)
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=2e5+5;
int A[N],ref[N];
inline int read()
{
	int now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now;
}
inline LL readll()
{
	LL now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now;
}
bool Check(int x,int n,int m,LL T)
{
	LL sum=0;//longlongaaaTAT
	for(int res=0,now=0,i=1,val=ref[x]; i<=n; ++i)
		if(A[i]<=val)
		{
			if((T-=A[i])<0) return 0;
			if(++res>=x) return 1;
			sum+=A[i];
			if(++now==m) now=0, T-=sum, sum=0;
		}
	return 0;
}
int main()
{
	ref[0]=1;
	for(int Ts=read(); Ts--; )
	{
		const int n=read(),m=read(); const LL t=readll();
		for(int i=1; i<=n; ++i) ref[i]=A[i]=read();
		std::sort(ref+1,ref+1+n);
		int l=1,r=n,mid,ans=0;
		while(l<=r)
			if(Check(mid=l+r>>1,n,m,t)) ans=mid, l=mid+1;
			else r=mid-1;
		printf("%d %d\n",ans,ref[ans]);
	}
	return 0;
}
F.Debate(贪心)
记四种人分别是\(1,2,3,4\)。显然\(2,3\)可以同时选,然后选一个\(4\)可以多选一个\(1/2+3\)。排序从大到小选就行了。
//46ms	6100KB
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <functional>
#define pc putchar
#define gc() getchar()
typedef long long LL;
const int N=4e5+5;
int val[4][N];
inline int read()
{
	int now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now;
}
inline int read01()
{
	int now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*2+c-48,c=gc());
	return now;
}
int main()
{
	const int n=read();
	int cnt[4]={0};
	for(int i=1,type; i<=n; ++i) type=read01(), val[type][++cnt[type]]=read();
	if(!cnt[3]&&(!cnt[1]||!cnt[2])) return puts("0"),0;
	for(int i=0; i<4; ++i) std::sort(val[i]+1,val[i]+cnt[i]+1,std::greater<int>());
	int p0=1,p1=1,p2=1,p3=1,ans=0;
	for(; p1<=cnt[1]&&p2<=cnt[2]; ans+=val[1][p1++]+val[2][p2++]);
	for(int i=1; i<=cnt[3]; ++i)
	{
		if(val[1][p1]+val[2][p2]>val[0][p0]) ans+=val[1][p1++]+val[2][p2++];
		else ans+=val[0][p0++];
		ans+=val[3][i];
	}
	printf("%d\n",ans);
	return 0;
}
H.BerOS File Suggestion(后缀自动机)
怎么写AC自动机、写Hash的都有... 这不是BZOJ2780吗?
粘过代码来就完了。然而我粘错了WA了两次。
//77ms	17500KB
#include <cstdio>
#include <cctype>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define pc putchar
#define gc() getchar()
typedef long long LL;
const int N=10005*10;
using namespace std;
int mp[233];
string str[10005];
struct Suffix_Automaton
{
	int tot,las,fa[N],len[N],son[N][40],cnt[N],bef[N];
	void Insert(int c,int now)
	{
		int np=++tot,p=las; len[las=np]=len[p]+1;
		for(; p&&!son[p][c]; p=fa[p]) son[p][c]=np;
		if(!p) fa[np]=1;
		else
		{
			int q=son[p][c];
			if(len[q]==len[p]+1) fa[np]=q;
			else
			{
				int nq=++tot;
				len[nq]=len[p]+1, bef[nq]=bef[q], cnt[nq]=cnt[q];
				memcpy(son[nq],son[q],sizeof son[q]);
				fa[nq]=fa[q], fa[q]=fa[np]=nq;
				for(; son[p][c]==q; p=fa[p]) son[p][c]=nq;
			}
		}
		for(; bef[np]!=now&&np; np=fa[np])
			++cnt[np], bef[np]=now;
	}
	void Query(char *s,int l)
	{
		int x=1;
		for(int i=0; i<l; ++i) x=son[x][mp[s[i]]];
		cout << cnt[x] << ' ' << str[bef[x]] << '\n';
	}
}sam;
inline int read()
{
	int now=0,f=1;register char c=gc();
	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
	for(;isdigit(c);now=now*10+c-48,c=gc());
	return now*f;
}
int main()
{
	static char s[233];
	int cnt=0; mp['.']=cnt++;
	for(int i='0'; i<='9'; ++i) mp[i]=cnt++;
	for(int i='a'; i<='z'; ++i) mp[i]=cnt++;
	int n=read(); sam.tot=1;
	for(int i=1; i<=n; ++i)
	{
		scanf("%s",s), str[i]=s;
		sam.las=1;
		for(int j=0,l=strlen(s); j<l; ++j) sam.Insert(mp[s[j]],i);
	}
	str[0]="-";
	for(int Q=read(); Q--; scanf("%s",s), sam.Query(s,strlen(s)));
	return 0;
}
I.Privatization of Roads in Berland(网络流)
\(Description\)
给定一张\(n\)个点\(m\)条边的无向图,以及一个整数\(k\)。你需要给每一条边染一种颜色。颜色种类无限多,每种颜色最多用两次,且对于任意一个点,和它相连的边的颜色不能超过\(k\)种。求一种可行的染色方案。
\(n,m\leq600\)。
\(Solution\)
设\(dgr_i\)为\(i\)的度数。那么如果\(dgr_i\leq k\),\(i\)连的边的颜色是什么都无所谓。否则需要让\(2(dgr_i-k)\)条边两两配对。
一条边在一个点处配对了就不能在另一个点处配对。对每条边\(i\ (u,v)\)连边\((u\to i,1),(v\to i,1),(i\to T,1)\),每个点\(x\)连边\((S\to x,\max(0,\ 2(d_x-k)))\),看最大流是否等于\(\sum\max(0,\ 2(d_x-k))\)即可。
不写代码惹。
2018-2019 ICPC, NEERC, Southern Subregional Contest的更多相关文章
- Codeforces 2018-2019 ICPC, NEERC, Southern Subregional Contest
		
2018-2019 ICPC, NEERC, Southern Subregional Contest 闲谈: 被操哥和男神带飞的一场ACM,第一把做了这么多题,荣幸成为7题队,虽然比赛的时候频频出锅 ...
 - 2018.10.20 2018-2019 ICPC,NEERC,Southern Subregional Contest(Online Mirror, ACM-ICPC Rules)
		
i207M的“怕不是一个小时就要弃疗的flag”并没有生效,这次居然写到了最后,好评=.= 然而可能是退役前和i207M的最后一场比赛了TAT 不过打得真的好爽啊QAQ 最终结果: 看见那几个罚时没, ...
 - 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)
		
A. Find a Number 找到一个树,可以被d整除,且数字和为s 记忆化搜索 static class S{ int mod,s; String str; public S(int mod, ...
 - 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) Solution
		
从这里开始 题目列表 瞎扯 Problem A Find a Number Problem B Berkomnadzor Problem C Cloud Computing Problem D Gar ...
 - 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) Solution
		
A. Find a Number Solved By 2017212212083 题意:$找一个最小的n使得n % d == 0 并且 n 的每一位数字加起来之和为s$ 思路: 定义一个二元组$< ...
 - Codeforces1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)总结
		
第一次打ACM比赛,和yyf两个人一起搞事情 感觉被两个学长队暴打的好惨啊 然后我一直做傻子题,yyf一直在切神仙题 然后放一波题解(部分) A. Find a Number LINK 题目大意 给你 ...
 - codeforce1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) 题解
		
秉承ACM团队合作的思想懒,这篇blog只有部分题解,剩余的请前往星感大神Star_Feel的blog食用(表示男神汉克斯更懒不屑于写我们分别代写了下...) C. Cloud Computing 扫 ...
 - 【*2000】【2018-2019 ICPC, NEERC, Southern Subregional Contest  C 】Cloud Computing
		
[链接] 我是链接,点我呀:) [题意] [题解] 我们可以很容易知道区间的每个位置有哪些安排可以用. 显然 我们优先用那些花费的钱比较少的租用cpu方案. 但一个方案可供租用的cpu有限. 我们可以 ...
 - 2018-2019 ICPC, NEERC, Southern Subregional Contest (codeforces 1070)
		
A. 直接从状态(0,0)bfs, 这样一定是最小的 #include <iostream> #include <sstream> #include <algorithm ...
 
随机推荐
- @JoinColumn解释
			
@JoinColumn与@Column标记一样,是用于注释表中的字段的.它的属性与@Column属性有很多相同之处,这里就不详细讲述.请读者参阅5.2.2小节中有关@Column属性的部分. l ...
 - How to delete VSTS Project
			
Buiding is so easy , Where is deleting ? C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7 ...
 - 模拟stringBeanFactory解析xml
			
思路:根据源码分析,将配置Bean类信息存放到xml文件中,通过解析xml, 然后反射拿到对象 存放到集合中 这里选择hashmap(键放置类名,值放置对象)存放,使用时使用get方法通过键(类名)拿 ...
 - 解决本地SqlServer无法连接远程服务器数据库,错误10060
			
本地SqlServer 连不上服务器的数据库环境,错误信息如下图,折腾来折腾去,最终还是解决了 第一步 查看服务器本地端口是否已经打开,查看方法:首先向C:\Windows\System32文件夹添加 ...
 - 第十五节、OpenCV学习(四)图像平滑与滤波
			
图像的平滑与滤波 平滑滤波是低频增强的空间域滤波技术,是图像模糊.消除噪声. 一.2D滤波器cv2.filter2D() 对于2D图像可以进行低通或者高通滤波操作,低通滤波(LPF)有利于去噪声,模糊 ...
 - python中的多线程和多进程编程
			
注意:多线程和多线程编程是不同的!!! 第一点:一个进程相当于一个要执行的程序,它会开启一个主线程,多线程的话就会再开启多个子线程:而多进程的话就是一个进程同时在多个核上进行: 第二点:多线程是一种并 ...
 - 题解-HAOI2018全套
			
去冬令营转了一圈发现自己比别人差根源在于刷题少,见过的套路少(>ω<) 于是闲来无事把历年省选题做了一些 链接放的都是洛谷的,bz偷懒放的也是链接 AM.T1 奇怪的背包 Problem ...
 - Windows Server 2012安装.NET Framework 3.5
			
1 文件获取地址 链接:https://pan.baidu.com/s/1o7wykEKKrzbVslSeHbBigA 提取码:e59o 2 安装原因 在Windows Server 2012上安装一 ...
 - 题解 P3246 【[HNOI2016]序列】
			
很久之前做过这道题,但是跑得贼慢,现在用了可以被卡成 n m 的笛卡尔树做法,发现跑得贼快[雾 noteskey 介绍一种复杂度错误然鹅在随机数据下跑得贼快的算法: 笛卡尔树 方法就是 \(O~ n\ ...
 - Beta答辩总结
			
组员名单 短学号 姓名 备注 409 后敬甲 组长 301 蔡文斌 315 黄靖茹 423 刘浩 317 黄泽 328 卢泽明 617 葛亮 344 张杰 348 朱跃安 链接汇总 组长博客:后敬甲 ...