1. 程式人生 > >Codeforces 272D Dima and Two Sequences【思維+模擬】

Codeforces 272D Dima and Two Sequences【思維+模擬】

D. Dima and Two Sequences time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output

Little Dima has two sequences of points with integer coordinates: sequence (a1, 1), (a2, 2), ..., (an, n) and sequence (b1, 1), (b2, 2), ..., (bn, n).

Now Dima wants to count the number of distinct sequences of points of length n that can be assembled from these sequences, such that the x-coordinates of points in the assembled sequence will not decrease

. Help him with that. Note that each element of the initial sequences should be used exactly once in the assembled sequence.

Dima considers two assembled sequences (p1, q1), (p2, q2), ..., (pn, qn) and (x1, y1), (x2, y2), ..., (xn, yn) distinct, if there is such i (1 ≤ i ≤ 2·n), that (pi

, qi) ≠ (xi, yi).

As the answer can be rather large, print the remainder from dividing the answer by number m.

Input

The first line contains integer n (1 ≤ n ≤ 105). The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109). The third line contains nintegers b1, b2, ..., bn (1 ≤ bi ≤ 109

). The numbers in the lines are separated by spaces.

The last line contains integer m (2 ≤ m ≤ 109 + 7).

Output

In the single line print the remainder after dividing the answer to the problem by number m.

Examples input
1
1
2
7
output
1
input
2
1 2
2 3
11
output
2
Note

In the first sample you can get only one sequence: (1, 1), (2, 1).

In the second sample you can get such sequences : (1, 1), (2, 2), (2, 1), (3, 2)(1, 1), (2, 1), (2, 2), (3, 2). Thus, the answer is 2.


題目大意:

給出N個數對(a1,1),(a2,1),(a3,1)....................(an,1);

再給出N個數對(b1,1),(b2,1),(b3,1)....................(bn,1);

我們需要將這2*N個數對,按照第一個元素從小到大排序,問我們有多少種不同的排列方式。結果模m;

思路:

①首先我們將序列按照第一個元素從小到大排序,如果有相同,那麼按照第二個元素從小到大排序。

②我們知道,Ans=ans(1,x)+ans(2,x)+ans(3,x)+.............這裡ans(1,x)表示數對第一個元素為1的排列方式。

根據高中知識有:ans(1,x)=A(n,n)/Z.這裡n表示數對以1作為第一個元素的數對個數。Z=(1<=y<=n)πA(y,y),這裡y表示數對(1,y)的個數。

排列組合的知識,並不難。

③但是我們知道這裡涉及到的除法,我們不能直接用逆元求,因為m這個數值是不定的。所以我們考慮在式子上進行化簡。

我們知道,A(y,y)的值要麼是1,要麼是2,因為我們知道,以數字y作為第二個元素出現的數對最多隻有兩個。

所以我們這裡就可以暴力判定一下,然後化簡式子了。

④口述相對比較簡約,具體參考程式碼理解。

Ac程式碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
    int x,y;
}c[350000];
#define ll __int64
int cmp(node a,node b)
{
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}
int main()
{
    int n,mod;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
        {
            int tmp;scanf("%d",&tmp);
            c[i].x=tmp,c[i].y=i;
        }
        for(int i=1;i<=n;i++)
        {
            int tmp;scanf("%d",&tmp);
            c[i+n].x=tmp,c[i+n].y=i;
        }
        scanf("%d",&mod);
        n*=2;
        sort(c+1,c+1+n,cmp);
        queue<int>s;
        for(int i=1;i<=n;i++)
        {
            int ss=i;
            int ee=i;
            while(ee<=n&&c[ee].x==c[ss].x)
            {
                ee++;
            }
            ee--;
            int cnt=0;
            for(int j=ss;j<ee;j++)
            {
                if(c[j].y==c[j+1].y&&c[j].x==c[j+1].x)cnt++;
            }
            for(int j=1;j<=ee-ss+1;j++)
            {
                if(j%2==0)
                {
                    if(cnt>=1)
                    {
                        s.push(j/2);
                        cnt--;
                    }
                    else s.push(j);
                }
                else s.push(j);
            }
            i=ee;
        }
        ll output=1;
        while(!s.empty())
        {
            ll u=s.front();s.pop();
            output=output*u;
            output%=mod;
        }
        printf("%I64d\n",output);
    }
}