Cantor Expand optimization

Cantor expansion is not difficult to implement, just a 25 lines:

. 1 #include <bits / STDC ++ H.>
 2  the using  namespace STD;
 . 3  
. 4  int n-, F [ . 19 ];
 . 5  int main () {
 . 6      Scanf ( " % D " , & n-);
 . 7      F [ 0 ] = . 1 ; // note 
. 8      for ( int I = . 1 ; I <= 10 ; I ++) F [I] = F [I- . 1 ] I *; // pre-factorial 
. 9      the while (N--) // number of data sets 
10      {
. 11          int ANS = 1 ; // each string are incremented by one rank, the above mentioned 
12 is          String S;
 13 is          CIN >> S;
 14          int len = s.length (); // get the length of the string 
15          for ( int I = 0 ; I <len; I ++ )
 16          {
 . 17              int K = 0 ;
 18 is              for ( int J = I + . 1 ; J <len; J ++ )
 . 19                  IF (S [I]> S [J]) K ++; / / record a few less than the current character after the current character 
20             K * = F + ANS [len-I- . 1 ]; // Note i starts from 0, it is. 1-i-len 
21 is          }
 22 is          the printf ( " % D \ n- " , ANS);
 23 is      }
 24      return  0 ;
 25 }
View Code

But the time complexity reached len 2 (len here of course is only 11, in addition to an exhaustive can too)

 

But if this question is it? (Reference Luo Gu P5637)

P5367 [template] Cantor Expand

Title Description

Seeking 1~N of a full array given in all 1~N Ranked whole arrangement. Results of 998,244,353 modulo.

Input Format

The first line of a positive integer N .

The second line of N positive integers, indicates 1~N one full array.

Output Format

Line a non-negative integer, it represents the answer to 9,982,443,539 values modulo.

Sample input and output

Input # 1 
3
2 1 3
Output # 1 
3
Input # 2 
4
1 2 4 3
Output # 2 
2

Description / Tips

For 10% of the data, . 1 N . 1 0.

For 50% of the data, . 1 N . 5 0 0 0.

For 100% data, 1≤N≤1000000

 

If you do expand the traditional Cantor, the time complexity of O (the n- 2 ), can only take 50 minutes (that's pretty good, a lot of high points than violence)

We consider it to maintain a small number of values behind each number with a data structure, naturally thought of the tree line weights (in fact, I would not Fenwick tree) .

Leaf node tree line maintenance is the number of leaf nodes corresponding to the number that appears (I do not know, specifically looking at the code). All numbers inserted first, followed by the i-th and 1 to find a [i] -1 interval done after deleting the number, the number of duplicates back to prevent generation of a wrong answer. The time complexity of O (logn).

On the code:

. 1 #include <bits / STDC ++ H.> // always remember modulus, as much as possible to reduce the probability of WA 
2  #define P 998 244 353
 . 3  #define N 1,000,009
 . 4  the using  namespace STD;
 . 5  
. 6  int n-, ANS = . 1 , A [N ], SUM [N << 2 ]; 
 . 7  Long  Long F [N]; // this question only memory limit 31.25MB, the first time the full long long found MLE, the second full burst int WA, the last part of the opening pressure before the memory is too long long 
. 8  void the Update ( int RT, int L, int R & lt, int X, int C, int FG) //fg is the flag, flag 
. 9  {
 10      IF (R & lt && L == L == X)
 . 11      {
 12 is          IF (fg == . 1 ) SUM [RT] + = C; // if it is inserted, sum is incremented C 
13 is          the else SUM [RT] - = C; // if it is deleted, sum decremented C 
14          return ;
 15      }
 16      int MID = (L + R & lt) >> . 1 ;
 . 17      IF (X <= MID) the Update (RT << . 1 , L, MID, X, C, FG);
 18 is      the else the Update (RT << . 1 | . 1 , MID + . 1 , R & lt, X, C, FG);
 . 19     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
20 }
21 
22 int Query(int rt,int l,int r,int x,int y)
23 {
24     if(l==x && r==y) return sum[rt];
25     int mid=(l+r)>>1;
26     if(y<=mid) return Query(rt<<1,l,mid,x,y);
27     else if(x>mid) return Query(rt<<1|1,mid+1,r,x,y);
28     else return Query(rt<<1,l,mid,x,mid)+Query(rt<<1|1,mid+1,r,mid+1,y);
29 }
30 int main(){
31     memset(sum,0,sizeof(sum));
32     scanf("%d",&n);
33     f[0]=1;//注意 
34     for(int i=. 1 ; I <= 1,000,009 ; I ++) F [I] = F [I- . 1 ]% P * I% P; // factorial 
35      for ( int I = . 1 ; I <= n-; I ++ )
 36      {
 37 [          Scanf ( " % D " , A & [I]);
 38 is          the Update ( . 1 , . 1 , n-, A [I], . 1 , . 1 ); // the number of each segment is inserted into the tree, the weight 
39      }
 40      for ( int = I . 1 ; I <= n-; I ++ )
 41 is      {
 42 is         IF (A [I] == . 1 ) // If a [i] == 1, then the answer does not contribute to a certain number, delete 
43 is          {
 44 is              the Update ( . 1 , . 1 , n-, A [I], . 1 , 0 );
 45              Continue ;
 46 is          }
 47          ANS = (Query ANS + ( . 1 , . 1 , n-, . 1 , A [I] - . 1 )% P * F [Ni] P%)% P; // update answer 
48          the Update ( . 1 , . 1 , n-, A [I], . 1 , 0 ); // delete the number 
49     }
50     printf("%d\n",(ans+P)%P);
51     return 0;
52 }
View Code

 

 

Guess you like

Origin www.cnblogs.com/Darkring/p/11366979.html