Codeforces Round #469 (Div. 2) D 数学递归 E SCC缩点
Codeforces Round #469 (Div. 2)
D. A Leapfrog in the Array
题意:n 个数,一开始按图1 放置,每次操作可以把最后的一个数移到最后的一个空格里。有 q 个询问,每次询问有 xi,问最后不能移动时,第 xi 个位置是什么数。
tags:从 xi 位置往后面推,每次移到奇数位置或偶数位置。
// 469 D
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi first
#define se second
typedef long long ll;
const int N = ;
ll solve(ll flag, ll xi, ll len, ll sum)
{
if(flag) {
if(!(xi&)) return sum + xi/;
else return solve(!(len&), (xi+)/, (len+)/, sum+len/);
}
else {
if(xi&) return sum + (xi+)/;
else return solve(len&, (xi+)/, len/, sum+(len+)/);
}
}
int main()
{
ll n; int q;
scanf("%lld%d", &n, &q);
ll xi;
while(q--)
{
scanf("%lld", &xi);
printf("%lld\n", solve(, xi, n, ));
}
return ;
}View CodeE. Data Center Maintenance
蛇皮题。。。读了20 分钟题都没读懂。。。
题意:
某公司有 n 个数据中心,有 m 个客户,每个客户的信息都存在两个不同的中心里。 一天有 h 个小时,第 i 个数据中心要在第 i 小时进行维护,期间客户不能从这个中心获取信息。 假设第 i 个客户的信息存在 c1、c2里,题目保证 c1、c2 不会在同一时间维护。
这个公司要做个实验,要选出至少一个中心,把这些中心的维护时间往后推一个小时。 问你最少要选出多少个中心,使得不管在哪个小时,任何客户都可以获取到他们自己的信息。
tasg:强连通缩点
一开始是想把 m 个客户当 m 条边建图,发现做不了。。。
其实我们只要在 m 条边里选择需要的边建图,即 c1和 c2, 如果 (U[c1]+1)%h == U[c2] ,就表明 c1 推后一个小时会和 c2 重合,连边 c1->c2 。
然后就是缩点,最后在缩点后图中找出度为 0 的点,保证 size 最小即可。
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi first
#define se second
typedef long long ll;
const int N = ;
struct SCC
{
struct Edge { int from, to, next; } e[N];
int dfn[N], low[N];
int head[N], tot, Belong[N], tot1, cnt;
vector< int > ans[N];
stack< int > Stack;
bool instack[N];
void Addedge(int u, int v) {
e[tot] = (Edge){ u, v, head[u] }; head[u]=tot++;
}
void Init() {
mes(head, -);
}
void Tarjan(int u)
{
dfn[u] = low[u] = ++tot1;
Stack.push(u); instack[u]=true;
for(int i=head[u]; i!=-; i=e[i].next)
{
int to = e[i].to;
if(dfn[to]==) {
Tarjan(to);
low[u] = min(low[u], low[to]);
}
else if(instack[to]) {
low[u] = min(low[u], dfn[to]);
}
}
if(dfn[u] == low[u]) {
++cnt;
while(!Stack.empty()) {
int End=Stack.top(); Stack.pop();
instack[End] = false;
ans[cnt].PB(End);
Belong[End] = cnt;
if(End == u) break;
}
}
}
} scc;
int U[N], out[N];
vector< int > ans;
int main()
{
scc.Init();
int n, m, h;
scanf("%d%d%d", &n, &m, &h);
rep(i,,n) scanf("%d", &U[i]);
int c1, c2;
rep(i,,m)
{
scanf("%d%d", &c1, &c2);
if((U[c1]+)%h == U[c2]) scc.Addedge(c1, c2);
if(U[c1] == (U[c2]+)%h) scc.Addedge(c2, c1);
}
rep(i,,n) if(scc.dfn[i]==) scc.Tarjan(i);
int u, v;
rep(i,,scc.tot-)
{
u=scc.e[i].from, v=scc.e[i].to;
if(scc.Belong[u] != scc.Belong[v]) {
++out[scc.Belong[u]];
}
}
int ans1=;
rep(i,,scc.cnt) {
if(out[i]==) {
if(ans1==) ans1=i;
else if(scc.ans[i].size()<scc.ans[ans1].size()) ans1=i;
}
}
printf("%d\n", scc.ans[ans1].size());
for(int i : scc.ans[ans1]) printf("%d ", i);
return ;
}View Code 相关推荐
xceman 2020-10-13
算法与数学之美 2020-10-07
Anscor 2020-10-05
liwg0 2020-09-08
数学爱好者 2020-08-31
thermodynamicB 2020-08-11
夕加加 2020-07-20
willowwgx 2020-07-18
kuoying 2020-07-16
Anscor 2020-07-14
starletkiss 2020-07-08
kingzone 2020-06-27
xceman 2020-06-27
算法与数学之美 2020-06-21
kuoying 2020-06-21
秒懂数学 2020-06-17