Codeforces Round #546 (Div. 2) D. Nastya Is Buying Lunch

题意:

长度为n的数组{pi},m对关系(a,b),如果a正好在数组中位于b的前一个位置,则可以交换a和b,问最多可以让pn的位置往前移动多少

题解:

如果pn可以往前走k步,他肯定可以和pk交换。如果pk后面的数都可与他交换,则最后可以使pn和pk互换,使pn移动到pk的位置

#include <bits/stdc++.h>
//#pragma comment(linker, ”/STACK:36777216“)

using namespace std;

typedef long long ll;
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define all(a) a.begin(), a.end()
#define db long double

int n, m;
vector<int> a, was;
vector<vector<int> > g;

int main(){
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    a.resize(n);
    g.resize(n);
    was.resize(n);
    for (int i = 0; i < n; i++) cin >> a[i], a[i]--;
    for (int i = 0; i < m; i++){
        int w1, w2;
        cin >> w1 >> w2;
        w1--; w2--;
        g[w1].pb(w2);
    }

    reverse(all(a));
    int ans = 0;

    for (int i = 0; i < n; i++) was[i] = 0;
    was[a[0]] = 1;
    int cnt = 1;
    for (int i = 1; i < n; i++){
        int cnt2 = 0;
        for (int to : g[a[i]]){
            if (was[to]) cnt2++;
        }
        if (cnt == cnt2){
            ans++;
        } else {
            was[a[i]] = 1;
            cnt++;
        }
    }

    cout << ans;
}

原文地址:https://www.cnblogs.com/hyfer/p/10534558.html

时间: 2024-10-08 12:46:00

Codeforces Round #546 (Div. 2) D. Nastya Is Buying Lunch的相关文章

Codeforces Round #546 (Div. 2) C. Nastya Is Transposing Matrices

C. Nastya Is Transposing Matrices time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Nastya came to her informatics lesson, and her teacher who is, by the way, a little bit famous here gave he

Nastya Hasn&#39;t Written a Legend(Codeforces Round #546 (Div. 2)E+线段树)

题目链接 传送门 题面 题意 给你一个\(a\)数组和一个\(k\)数组,进行\(q\)次操作,操作分为两种: 将\(a_i\)增加\(x\),此时如果\(a_{i+1}<a_i+k_i\),那么就将\(a_{i+1}\)变成\(a_i+k_i\),如果\(a_{i+2}<a_i+k_i\),则将\(a_{i+2}\)变成\(a_{i+1}+k_{i+1}\),以此类推. 查询\(\sum\limits_{i=l}^{r}a_i\). 思路 我们首先存下\(k\)数组的前缀和\(sum1\),

Codeforces Round #546 (Div. 2) D 贪心 + 思维

https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则,假如u在v相邻前面,那么u和v可以交换位置,问你是队列最后一个人的时候你最前可以换到前面哪里 题解 因为相邻才能换,所以最后一个换到前面一定是一步一步向前走,所以不存在还要向后走的情况 设最后一个为u,假设前面有一个能和u换位置的集合,那么需要将这些点尽量往后移动去接u 假设前面有一个不能和u换位置的集合S,

Codeforces Round #546 (Div. 2)

http://codeforces.com/contest/1136 A #include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; int N, K; struct Node { int L; int R; }node[maxn]; int main() { scanf("%d", &N); for(int i = 1; i <= N; i ++) scanf("

Codeforces Round #489 (Div. 2) E. Nastya and King-Shamans

这道题的算法是: i从1开始,首先求sum(1-i),然后在[i+1, n]中找到第一个a[j]>=sum(1, i) 如果a[j]==sum(1, i)结束搜索,否则令i=j,循环过程 因为每次做完一次之后sum会至少增大一倍,所以一个查询的复杂度会维持到log(Max(a[i])) 需要维护 区间最大值和区间和 的线段树来实现算法 #include <iostream> #include <cstdio> #include <cmath> #include &

Codeforces Round #489 (Div. 2)

Codeforces Round #489 (Div. 2) A. Nastya and an Array #include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define frep(i,a,b) for(int i=a;i>=b;--i) #define mem(W) memset(W,0,sizeof(W)) #define pb push_back typedef long long ll; c

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #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

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我