"NOI2015" Sushi party (pressure DP)

Source: Internet
Author: User

"Problem description" to celebrate NOI's successful opening, the organizers prepared a sushi dinner for everyone. Small G and small W as participants in the NOI, was also invited to participate in the sushi dinner. At the gala dinner, the organizers offered n?1 different types of sushi, numbered,?, n?1, where the flavor of the sushi was i+1 (i.e. the delicacy of sushi from 2 to n). Now small G and small w want to choose some kinds of sushi for each person to taste, they prescribe a tasting plan for disharmony when and only if: small g taste of sushi There is a delicious x of sushi, small W taste of sushi There is a delicious y sushi, and X and Y is not coprime. Now small G and small W want to count a total of how many kinds of harmonious tasting sushi scheme (for a given positive integer p modulus). Note that a person may not eat any sushi.
The 1th line of the input format input file contains 2 positive integers (2≤n≤500, 0 < p≤10,000,000,000), separated by a single space, indicating a common type of sushi, and the final harmonious scheme number to be modeled.
The output format output line contains 1 integers representing the result of the solution modulo p that is being asked.

This is my first time to participate in the NOI "Sync Match" 23333. In the teacher's words, "feel the atmosphere" ...

Day1 first water over, looked at the second question: I go like a tree chain split! I went to the tree chain to learn yesterday! ...... Then I had a violent qaq in silence.

Then there is the third question. Just see this question, there seems to be no idea ... Try to think of the pressure DP, but there are more than 80 prime numbers within 500, it is not allowed to do the look (anyway, can't think out) . And then he played a watch silently Qaq

Sure enough, I was too weak ... Not much to say, the puzzle. (This is my view of the great God's code yy out, if there is a mistake please point out, greatly appreciated)

First of all, the selection of a number is actually the quality factor of its selection, so that only consider the quality factor.

Obviously for any number a, if the decomposition of its mass factor , at most, there is a qualitative factor greater than sqrt (n). Therefore, you can calculate the two cases separately, and then merge to find the answer:

  • For the case of a mass factor p containing only less than or equal to sqrt (n):
    • Set F[s] The number of scenarios for which a person chooses a mass factor of set S (the elements in S must all be used!) )
    • It is easy to draw f[s] = 2^|a| –sigma (s0| S0? s) (A is a set of the number of the mass factors that are all contained by S)
  • In case of a p0 containing a mass factor greater than sqrt (n):
    • Set G[I][S1][S2] to the first I greater than sqrt (n) of the prime number and its multiples , the number of sqrt (n) is selected less than the quality factor of S1, the other person selected as a S2 scheme
    • For each p0[i] there are only two choices: the first person to go or the second person to go (not the selected case is included two times, so the last need to subtract)
    • If P0[i] is the first person to go:
      • Set T[K][S1][S2] to count to the first k multiples of the current prime number, the number of sqrt (n) is S1, and the other person chooses a S2 scheme.
      • Set S0 as a set of prime numbers less than sqrt (n) for the K + 1 time times of the current prime number for a mass factor decomposition
      • T[K][S1][S2] can be transferred to T[K+1][S1][S2] and T[k+1][s1∪s0][s2] ((s1∪s0) ∩s2 =?)
      • Boundary: t[0][s1][s2] = g[i-1][s1][s2]
    • P0[i] by the second person, the same situation.
  • Finally, enumerate the Sa and Sb (SA∩SB =?), and then enumerate the S1 and S2 so that (SA∪S1) ∩ (SB∪S2) =?, ans cumulative f[sa] * F[SB] * G[M][S1][S2] can (M is the size of p0)

Notice that G, T is very large, and they are only related to the previous, it can be omitted from the first dimension.

Well, honestly, I'm looking at someone else's code to do this.

Must be careful not to use memset, memcpy!!! This thought 3^n and 4^n difference is not small, so the tle ...

The implementation has a lot of details, see the code: (Konjac Konjac code is very written down ...) Forgive me

#include <cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<cctype>#include<cassert>#include<ctime>#include<algorithm>#include<utility>#include<functional>#include<iostream>using namespaceStd;typedefLong LongLL;Const intMAXN =505, MAXM1 =Ten, MAXM2 = -, Maxs =1<<MAXM1;intN; LL P;///m1:the Number of primes<= sqrt (N)///m2:the number of primes > sqrt (N)//ps[i]: The set of primes of number I
///A[i][j]: The i-th primes Pi * J<= N (Pi >sqrt (N))intM1, M2, PS[MAXN], a[maxm2][ -];intSbound, SAll; LL F[MAXS]; LL g[2][MAXS][MAXS];intGidx;inlinevoidAdd (LL &A, LL b) {a+=b; if(A >= P)///err#2: ">" instead of ">="A-=P; if(A <0) A+=P;} inline ll Mul (ll A, ll b) {returnA * b%P;}inlinevoidAdd (LL A[][maxs],ConstLL B[][maxs],intd) {     for(intS =0; S < Sbound; s++) {        intSS = SAll ^S, S0;  for(S0 = SS; S0; S0 = (S0-1) &SS) Add (A[s][s0], D*B[s][s0]); Add (A[s][s0], D*B[s][s0]); }}inlinevoidCPY (LL A[][maxs],ConstLL B[][maxs]) {     for(intS =0; S < Sbound; s++) {        intSS = SAll ^S, S0;  for(S0 = SS; S0; S0 = (S0-1) &SS) A[s][s0]=B[S][S0]; A[S][S0]=B[S][S0]; }}voidinit () {Static BOOLFLAG[MAXN]; M1= M2 =0;  for(inti =2; I <= N; i++) {        if(Flag[i])Continue; Ps[i]|=1<<M1; if(I * I <=N) { for(intj =2I J <= N; J + =i) {flag[j]=true; PS[J]|=1<<M1; } M1++; } Else{M2++; a[m2][a[m2][0]=1] =i;  for(intj =2I J <= N; J + =i) {flag[j]=true; PS[J]|=1<<M1; a[m2][++a[m2][0]] =J; } }} sbound=1<<M1; SAll= Sbound-1;}voidCALCF () { for(intS =0; S < Sbound; s++) {F[s]=1;  for(inti =2; I <= N; i++)            if((S | Ps[i]) = =S) Add (F[s], f[s]); intS0;  for(S0 = (S-1) & S; S0; S0 = (S0-1) & S)///err#3: "S0 = S" instead of "S0 = (S-1) & S"Add (F[s],-F[s0]); if(S) Add (F[s],-F[s0]); }}ll t[2][MAXS][MAXS]; LL EMPTY[MAXS][MAXS];voidSelectA (inta[]) {     for(inti =1; I <= a[0]; i++) {        intCur = i &1, last = cur ^1; intmask = Ps[a[i]] ^Sbound;        CPY (T[cur], empty);  for(intS1 =0; S1 < Sbound; s1++) {            intSS = SAll ^S1, S2;  for(S2 = SS; S2; S2 = (S2-1) &SS) {                if(((S1 | mask) & S2) = =0) Add (t[cur][s1|Mask]                [S2], t[last][s1][s2]);            Add (T[cur][s1][s2], t[last][s1][s2]); } Add (T[cur][s1|Mask]            [S2], t[last][s1][s2]);        Add (T[cur][s1][s2], t[last][s1][s2]); }    }}voidSELECTB (inta[]) {     for(inti =1; I <= a[0]; i++) {        intCur = i &1, last = cur ^1; intmask = Ps[a[i]] ^Sbound;        CPY (T[cur], empty);  for(intS1 =0; S1 < Sbound; s1++) {            intSS = SAll ^S1, S2;  for(S2 = SS; S2; S2 = (S2-1) &SS) {                if((S1 & (S2 | mask)) = =0) Add (t[cur][s1][s2|mask], t[last][s1][s2]);            Add (T[cur][s1][s2], t[last][s1][s2]); }            if((S1 & mask) = =0) Add (t[cur][s1][s2|mask], t[last][s1][s2]);        Add (T[cur][s1][s2], t[last][s1][s2]); }    }}voidCALCG () {g[0][0][0] =1;  for(inti =1; I <= M2; i++) {        intCur = i &1, last = cur ^1, Curt = a[i][0] &1; CPY (G[cur], empty); ///err#1:forgot Reset G[cur]CPY (t[0], g[last]);        SelectA (A[i]); Add (G[cur], T[curt],1); CPY (t[0], g[last]);        SELECTB (A[i]); Add (G[cur], T[curt],1); Add (G[cur], g[last],-1); } gidx= M2 &1;} LL Solve (intSaintSb) {    if(Sa >Sb)return 0; LL Res=0,Base=Mul (F[sa], F[SB]);  for(intS1 =0; S1 < Sbound; s1++) {        intSS = SAll ^S1, S2;  for(S2 = SS; S2; S2 = (S2-1) &SS)if((Sa | S1) & (Sb | S2)) = =0) Add (res, mul (Base, G[gidx][s1][s2])); if((Sa | S1) & (Sb | S2)) = =0) Add (res, mul (Base, G[gidx][s1][s2])); }    if(Sa! =Sb) Add (res, res); ///e.g. res *= 2;    returnRes;}intMain () {Freopen ("dinner.in","R", stdin); Freopen ("Dinner.out","W", stdout); CIN>> N >>P;    Init ();    CALCF ();    CALCG (); LL ans=0;  for(intS1 =0; S1 < Sbound; s1++) {        intSS = SAll ^S1, S2;  for(S2 = SS; S2; S2 = (S2-1) &SS) Add (ans, solve (S1, S2));    Add (ans, solve (S1, S2)); } cout<< ans <<Endl; return 0;}

"NOI2015" Sushi party (pressure DP)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.