Educational Codeforces Round 10 C. Foe Pairs

来源:互联网 发布:ne80e端口物理层down 编辑:程序博客网 时间:2024/05/18 01:54

给你一个n的排列(n<=3*10^5),然后给你m个禁止的组合(m<=3*10^5),问你有多少个区间不包含任何一个禁止的组合。

思路:

1.O(n+m)

考虑每个位置,他的最远的右区间是多少,我们可以在输入m个禁止组合的时候,维护位置较小的那个数的最远位置,这样我们便知道了那些出现过的每个较小位置对应的最右位置。

然后逆序更新一遍每个位置的最右位置就行了,因为如果在他右边的位置的最远位置已经确定了,那么在他左边的最远位置的数也一定不能取到这个最远位置。


#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-12#define maxn 300100#define MOD 1000000007int n,m;int a[maxn];int pos[maxn];int cnt[maxn];int main(){    int t;    //scanf("%d",&t);    while(scanf("%d%d",&n,&m) != EOF)    {        for(int i = 1; i <= n; i++)        {            scanf("%d",&a[i]);            pos[a[i]] = i;            cnt[i] = n+1;        }        for(int i = 0; i < m; i++)        {            int x,y;            scanf("%d%d",&x,&y);            if(pos[x] > pos[y])                cnt[pos[y]] = min(cnt[pos[y]],pos[x]);            else                cnt[pos[x]] = min(cnt[pos[x]],pos[y]);        }        long long ans = 0;        for(int i = n-1; i > 0; i--)            cnt[i] = min(cnt[i],cnt[i+1]);//        for(int i = 1; i <= n; i++)//            printf("%d %d\n",i,cnt[i]);        for(int i = 1; i <= n; i++)            ans += (long long)(cnt[i] - i);        printf("%I64d\n",ans);    }    return 0;}


0 0