CodeForces Round #406 (Div. 2)

这一场打得真难受

 

A. The Monster

解个方程就好了。

但开个visit数组暴力判断也没问题。

可以看到这份代码实际上数组可能会越界,好在没人hack,也没有FST

A

 

B. Not Afraid

题意记不清了,反正差不多是道模拟。

开两个bool数组记录两个集合里的人出现过没有即可。

B

 

C. Berzerk

博弈论 DP SG函数

按照SG函数的定义直接DP。

具体细节看代码

C

 

D. Legacy

图论 最短路 线段树

本质上是个最短路问题,但是一条路可能有多个起点和一个终点,或者一个起点和多个终点。

一条条建边显然T飞,不实际建边的最短路也跑不过去。

于是就用到了一个黑科技:线段树优化建边。在线段树的每个结点上向它的子结点连边,边权为0。连起点/终点是一个区间的边的时候,只要连到线段树对应的结点即可。

INF值要设得特别大。

D

 

E.Till I Collapse

STL 贪心 乱搞

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<vector>
 8 using namespace std;
 9 const int mxn=300010;
10 int read(){
11     int x=0,f=1;char ch=getchar();
12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 int n;
17 int a[mxn];
18 int pre[mxn],nxt[mxn],hd[mxn];
19 int t[mxn];
20 void add(int x,int v){
21     if(!x)return;
22     while(x<=n){t[x]+=v;x+=x&-x;}return;
23 }
24 int ask(int x){
25     int res=0;
26     for(int i=18;i>=0;i--){
27         int p=res+(1<<i);
28         if(p<=n && t[p]<x){
29             x-=t[p];res=p;
30         }
31     }
32     return res+1;
33 }
34 int f[mxn];
35 vector<int>ve[mxn];
36 int main(){
37     int i,j;
38     n=read();
39     for(i=1;i<=n;i++){
40         a[i]=read();
41         pre[i]=hd[a[i]];
42         hd[a[i]]=i;
43     }
44     for(i=1;i<=n;i++)nxt[pre[i]]=i,ve[1].push_back(i);
45     for(i=1;i<=n;i++)if(!pre[i])add(i,1);
46 //    for(i=1;i<=n;i++)printf("i:%d nxt:%d\n",i,nxt[i]);
47     for(i=1;i<=n;i++){
48         if(i>1)add(nxt[i-1],1);//记录上一个影响
49         for(j=0;j<ve[i].size();j++){
50             int ne=ask(ve[i][j]+1);
51             ve[ne].push_back(ve[i][j]);
52             f[ve[i][j]]++;
53         }
54         add(i,-1);
55     }
56     for(i=1;i<=n;i++)printf("%d ",f[i]);
57     return 0;
58 }
E

 

posted @ 2017-03-25 22:04  SilverNebula  阅读(276)  评论(0编辑  收藏  举报
AmazingCounters.com