Codeforces Round #406 (Div. 1)
B题打错调了半天,C题想出来来不及打,还好没有挂题
AC:AB Rank:96 Rating:2125+66->2191
A.Berzerk
题目大意:有一个东东在长度为n的环上(环上点编号0~n-1),两个玩家,玩家1有a种操作可选,玩家2有b种操作可选,每种操作可以让这个东东向前走若干步,两个玩家轮流操作,谁先让东东走到0谁胜,求出双方都选最优操作的情况下,东东开始在1~n-1各位置时玩家1先手和玩家2先手会必胜,必败还是无限循环。(a,b<n<=7000)
思路:类似DFS或者BFS的乱找,每次确定一个必败状态时,能到该状态的所有状态都为必胜态,一个状态能到的所有状态都确定为必胜时,该状态必败,用数组记下每个状态还有几个能到的状态未被确定即可,最后无法确定的状态即为循环,总复杂度O((a+b)n)。
#include<cstdio>
char B[<<],*S=B,C;int X;
inline int read()
{
while((C=*S++)<''||C>'');
for(X=C-'';(C=*S++)>=''&&C<='';)X=(X<<)+(X<<)+C-'';
return X;
}
#define MN 7000
int n,s[],t[][MN+],u[MN*+],q[MN*+],l[MN*+],qn;
int d(int x,int y){return x*n+(y+n)%n;}
void lose(int);
void win(int p)
{
int x=p/n,y=p%n,i,v;
x^=;u[p]=;
for(i=;i<=s[x];++i)
{
v=d(x,y-t[x][i]);
if(!u[v]&&++l[v]==s[x])lose(v);
}
}
void lose(int p)
{
int x=p/n,y=p%n,i,v;
x^=u[p]=;
for(i=;i<=s[x];++i)
{
v=d(x,y-t[x][i]);
if(!u[v])win(v);
}
}
int main()
{
fread(B,,<<,stdin);
int i,x,y;
for(n=read(),x=;x<;++x)for(s[x]=read(),i=;i<=s[x];++i)t[x][i]=read();
u[n]=;lose();lose(n);
for(i=;i<n;++i)printf("%s ",u[i]?u[i]>?"Win":"Lose":"Loop");puts("");
for(i=;i<n;++i)printf("%s ",u[i+n]?u[i+n]>?"Win":"Lose":"Loop");
}
B.Legacy
题目大意:n个点,一个人一开始位于s,有q个走法供他选择,走法有3种种类:1.从v到u,花费w;2.从v到l~r中的一个点,花费w;3.从l~r中的一个点到v,花费w,求到各个点的最短路。(n,q<=100,000)
思路:线段树优化建图。第一类边直接连;第二类我们建一棵线段树,所有父亲向儿子连长度为0的边,表示到了该区间也能到达该区间中的点,每次我们让v连向表示[l,r]的O(log)个线段树节点即可;第三类我们再建一棵线段树,所有儿子向父亲连长度为0的边,这样每个点就能到达所有表示包含它的区间的线段树节点,每次我们让表示[l,r]的线段树上节点连向v即可。跑Dijkstra,总复杂度O((n+q)logn^2)。
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long
char B[<<],*S=B,C;int X;
inline int read()
{
while((C=*S++)<''||C>'');
for(X=C-'';(C=*S++)>=''&&C<='';)X=(X<<)+(X<<)+C-'';
return X;
}
#define MN 100000
#define N 131072
#define MV 524288
#define ME 5000000
#define d(x,y) make_pair(x,y)
struct edge{int nx,t,w;}e[ME+];
int h[MV+],en;ll ds[MV+];
typedef pair<ll,int> data;
priority_queue<data,vector<data>,greater<data> >pq;
inline void ins(int x,int y,int w){e[++en]=(edge){h[x],y,w};h[x]=en;}
void ins1(int l,int r,int f,int w)
{
for(l+=N-,r+=N+;l^r^;l>>=,r>>=)
{
if(~l&)ins(f+N,l+,w);
if( r&)ins(f+N,r-,w);
}
}
void ins2(int l,int r,int t,int w)
{
for(l+=N-,r+=N+;l^r^;l>>=,r>>=)
{
if(~l&)ins(l++(N<<),t+N,w);
if( r&)ins(r-+(N<<),t+N,w);
}
}
int main()
{
fread(B,,<<,stdin);
int n,m,i,s,a,b,c,d;ll x;
n=read();m=read();s=read();
for(i=;i<N;++i)
{
ins(i,i<<,);ins(i,i<<|,);
ins(i+N<<,i+(N<<),);ins(i+N<<|,i+(N<<),);
ins(i+N,i+N*,);ins(i+N*,i+N,);
}
while(m--)
{
a=read();b=read();c=read();d=read();
if(a==)ins(b+N,c+N,d);
if(a==)ins1(c,d,b,read());
if(a==)ins2(c,d,b,read());
}
memset(ds,,sizeof(ds));ds[s+N]=;pq.push(d(,s+N));
while(pq.size())
{
a=pq.top().second;x=pq.top().first;pq.pop();
for(i=h[a];i;i=e[i].nx)if(x+e[i].w<ds[e[i].t])
{
ds[e[i].t]=x+e[i].w;
pq.push(d(ds[e[i].t],e[i].t));
}
while(pq.size()&&pq.top().first>ds[pq.top().second])pq.pop();
}
for(i=;i<=n;++i)printf("%I64d ",ds[i+N]<ds[]?ds[i+N]:-);
}
C.Till I Collapse
题目大意:给定n个数,对于每个1<=k<=n,求把数列分成若干段,每段数字种数不超过k,至少分几段。(n<=100,000)
思路:对于k<=n^0.5,我们每次O(n)暴力统计答案,对于k>n^0.5,我们先预处理出k=n^0.5时分成的至多n^0.5段,每段的右端点和各种数字的出现次数,每次把所有右端点向右推即可知道k+1时的信息,右端点每向右推一位我们都只要O(1),总复杂度O(n^1.5)。
#include<cstdio>
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 100000
#define MK 320
int a[MN+],f[MK+][MN+],cnt[MK+],r[MK+],ans;
int main()
{
int n=read(),i,j,k;
for(i=;i<=n;++i)a[i]=read();
for(i=;i<=n&&i<=MK;++i)
{
for(ans=j=;j++<=n;)
if(j>n||(!f[][a[j]]++&&++cnt[]>i))
{
for(k=j>n?n:j;cnt[];--k)if(!--f[][a[k]])--cnt[];
if(j<=n)f[][a[j]]=cnt[]=;++ans;
}
printf("%d ",ans);
}
if(i<=n)
{
for(ans=j=;j<=n;r[ans]=++j)
if(!f[ans][a[j]]++&&++cnt[ans]>i)
{
--f[ans][a[j]];--cnt[ans];
++f[++ans][a[j]];++cnt[ans];
}
printf("%d ",ans);
}
for(++i;i<=n;++i)
{
for(j=;j<=ans;++j)
{
for(k=r[j];k<=n;r[j]=++k)
{
if(!--f[j+][a[k]])--cnt[j+];
if(!f[j][a[k]]++&&++cnt[j]>i)
{
if(!--f[j][a[k]])--cnt[j];
if(!f[j+][a[k]]++)++cnt[j+];
break;
}
}
if(k>n)ans=j;
}
printf("%d ",ans);
}
}
Codeforces Round #406 (Div. 1)的更多相关文章
- Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- Codeforces Round #406 (Div. 1) A. Berzerk 记忆化搜索
A. Berzerk 题目连接: http://codeforces.com/contest/786/problem/A Description Rick and Morty are playing ...
- 维护前面的position+主席树 Codeforces Round #406 (Div. 2) E
http://codeforces.com/contest/787/problem/E 题目大意:给你n块,每个块都有一个颜色,定义一个k,表示在区间[l,r]中最多有k中不同的颜色.另k=1,2,3 ...
- 区间->点,点->区间,线段树优化建图+dijstra Codeforces Round #406 (Div. 2) D
http://codeforces.com/contest/787/problem/D 题目大意:有n个点,三种有向边,这三种有向边一共加在一起有m个,然后起点是s,问,从s到所有点的最短路是多少? ...
- 有向图博弈+出度的结合 Codeforces Round #406 (Div. 2) C
http://codeforces.com/contest/787/problem/C 题目大意:有一个长度为n的环,第1个位置是黑洞,其他都是星球.已知在星球上(不含第一个黑洞)有一位神.有两个人, ...
- 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- Codeforces #Round 406(Div.2)
来自FallDream的博客,未经允许,请勿转载,谢谢. ------------------------------------------------------- 大家好,我是一个假人.在学习O ...
- Codeforces Round #406 (Div. 2) D. Legacy 线段树建模+最短路
D. Legacy time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- Codeforces Round #406 (Div. 2)滚粗记
A 一看到题,不是一道解不定方程的裸题吗,调了好久exgcd. 其实一个for就好了啊 B 一直WA ON TEST 7真是烦,一想会不会是编号太大了,又写了一个map版本,无用. 调了好久好久才发现 ...
随机推荐
- vim配置强悍来袭
vim 这个关键字,我不想再过多的解释,相信看到这里的同仁,对vim都有十七八分的理解,如果你还不知道vim是什么,自己找个黑屋子... 废话不多说,今天在这里主要说vim的,不带插件的配置,也就 ...
- 20145237 《Java程序设计》第八周学习总结
20145237 <Java程序设计>第八周学习总结 教材学习内容总结 第十五章 通用API 15.1 日志 日志API简介 • java.util.logging包提供了日志功能相关类与 ...
- 20145237《Java程序设计》实验报告一
实验一 Java开发环境的熟悉(Windows + Eclipse) 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 实验要求 1 ...
- scrapy csvfeed spider
class CsvspiderSpider(CSVFeedSpider): name = 'csvspider' allowed_domains = ['iqianyue.com'] start_ur ...
- 玩转Leveldb原理及源码--拙见1
可以说是不知天高地厚.. 可以说是班门弄斧.. 但是,我今天还就这样走了,我喜欢!!!!!! 注:后续文章,限于篇幅,不懂名词都有 紫色+下划线 超链接,有兴趣,可以查阅: 网上关于Leveldb 的 ...
- java实现红包的分配算法
个人推测,微信红包在发出的时候已经分配好金额.比如一个10元的红包发给甲乙丙三个人,其实在红包发出去的时候,已经确定了第一个会领取多少,第二个会领取多少金额. 而不是在领取的时候才计算的.下面贴出实现 ...
- 数据结构与算法 —— 链表linked list(02)
我们继续来看链表的第二道题,来自于leetcode: 两数相加 给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了 ...
- php的控制器链
控制器之间协同工作就形成了控制器链· 比如在一个控制器的方法中,创建另外一个·控制器,创建对象,然后调用第二个控制器方法,那么在第一个控制器分配给视图的变量,在 第二个控制器的方法中对应的视图也是可以 ...
- linux下安装redis和phpredis扩展
一.安装redis 1.下载redis-3.2.3.tar.gz wget http://download.redis.io/releases/redis-3.2.3.tar.gz 2.解压redis ...
- Python内置函数(34)——map
英文文档: map(function, iterable, ...) Return an iterator that applies function to every item of iterabl ...