Guest User

Untitled

a guest
Sep 15th, 2025
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.57 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #ifdef LOCAL
  5. #include "debug.hpp"
  6. #define dbg(x...) cerr << "[" << #x << "]=["; _print(x)
  7. #else
  8. #define dbg(x...)
  9. #endif
  10.  
  11. #define inf (long long)1e18
  12. #define endl "\n"
  13. #define x first
  14. #define y second
  15. #define all(x) (x).begin(),(x).end()
  16.  
  17. template <const int &MOD>
  18. struct modular_int
  19. {
  20. int val;
  21.  
  22. modular_int(int64_t v = 0)
  23. {
  24. if (v < 0)
  25. v = v % MOD + MOD;
  26. if (v >= MOD)
  27. v %= MOD;
  28. val = int(v);
  29. }
  30.  
  31. modular_int(uint64_t v)
  32. {
  33. if (v >= MOD)
  34. v %= MOD;
  35. val = int(v);
  36. }
  37.  
  38. modular_int(int v) : modular_int(int64_t(v)) {}
  39. modular_int(unsigned v) : modular_int(uint64_t(v)) {}
  40.  
  41. explicit operator int() const { return val; }
  42. explicit operator unsigned() const { return val; }
  43. explicit operator int64_t() const { return val; }
  44. explicit operator uint64_t() const { return val; }
  45. explicit operator double() const { return val; }
  46. explicit operator long double() const { return val; }
  47.  
  48. modular_int &operator+=(const modular_int &other)
  49. {
  50. val -= MOD - other.val;
  51. if (val < 0)
  52. val += MOD;
  53. return *this;
  54. }
  55.  
  56. modular_int &operator-=(const modular_int &other)
  57. {
  58. val -= other.val;
  59. if (val < 0)
  60. val += MOD;
  61. return *this;
  62. }
  63.  
  64. static unsigned fast_mod(uint64_t x, unsigned m = MOD)
  65. {
  66. #if !defined(_WIN32) || defined(_WIN64)
  67. return unsigned(x % m);
  68. #endif
  69. // Optimized mod for Codeforces 32-bit machines.
  70. // x must be less than 2^32 * m for this to work, so that x / m fits in an unsigned 32-bit int.
  71. unsigned x_high = unsigned(x >> 32), x_low = unsigned(x);
  72. unsigned quot, rem;
  73. asm("divl %4\n"
  74. : "=a"(quot), "=d"(rem)
  75. : "d"(x_high), "a"(x_low), "r"(m));
  76. return rem;
  77. }
  78.  
  79. modular_int &operator*=(const modular_int &other)
  80. {
  81. val = fast_mod(uint64_t(val) * other.val);
  82. return *this;
  83. }
  84.  
  85. modular_int &operator/=(const modular_int &other)
  86. {
  87. return *this *= other.inv();
  88. }
  89.  
  90. friend modular_int operator+(const modular_int &a, const modular_int &b) { return modular_int(a) += b; }
  91. friend modular_int operator-(const modular_int &a, const modular_int &b) { return modular_int(a) -= b; }
  92. friend modular_int operator*(const modular_int &a, const modular_int &b) { return modular_int(a) *= b; }
  93. friend modular_int operator/(const modular_int &a, const modular_int &b) { return modular_int(a) /= b; }
  94.  
  95. modular_int &operator++()
  96. {
  97. val = val == MOD - 1 ? 0 : val + 1;
  98. return *this;
  99. }
  100.  
  101. modular_int &operator--()
  102. {
  103. val = val == 0 ? MOD - 1 : val - 1;
  104. return *this;
  105. }
  106.  
  107. modular_int operator++(int)
  108. {
  109. modular_int before = *this;
  110. ++*this;
  111. return before;
  112. }
  113. modular_int operator--(int)
  114. {
  115. modular_int before = *this;
  116. --*this;
  117. return before;
  118. }
  119.  
  120. modular_int operator-() const
  121. {
  122. return val == 0 ? 0 : MOD - val;
  123. }
  124.  
  125. friend bool operator==(const modular_int &a, const modular_int &b) { return a.val == b.val; }
  126. friend bool operator!=(const modular_int &a, const modular_int &b) { return a.val != b.val; }
  127. friend bool operator<(const modular_int &a, const modular_int &b) { return a.val < b.val; }
  128. friend bool operator>(const modular_int &a, const modular_int &b) { return a.val > b.val; }
  129. friend bool operator<=(const modular_int &a, const modular_int &b) { return a.val <= b.val; }
  130. friend bool operator>=(const modular_int &a, const modular_int &b) { return a.val >= b.val; }
  131.  
  132. static const int SAVE_INV = int(1e6) + 5;
  133. static modular_int save_inv[SAVE_INV];
  134.  
  135. static void prepare_inv()
  136. {
  137. // Ensures that MOD is prime, which is necessary for the inverse algorithm below.
  138. for (int64_t p = 2; p * p <= MOD; p += p % 2 + 1)
  139. assert(MOD % p != 0);
  140.  
  141. save_inv[0] = 0;
  142. save_inv[1] = 1;
  143.  
  144. for (int i = 2; i < SAVE_INV; i++)
  145. save_inv[i] = save_inv[MOD % i] * (MOD - MOD / i);
  146. }
  147.  
  148. modular_int inv() const
  149. {
  150. if (save_inv[1] == 0)
  151. prepare_inv();
  152.  
  153. if (val < SAVE_INV)
  154. return save_inv[val];
  155.  
  156. modular_int product = 1;
  157. int v = val;
  158.  
  159. do
  160. {
  161. product *= MOD - MOD / v;
  162. v = MOD % v;
  163. } while (v >= SAVE_INV);
  164.  
  165. return product * save_inv[v];
  166. }
  167.  
  168. modular_int pow(int64_t p) const
  169. {
  170. if (p < 0)
  171. return inv().pow(-p);
  172.  
  173. modular_int a = *this, result = 1;
  174.  
  175. while (p > 0)
  176. {
  177. if (p & 1)
  178. result *= a;
  179.  
  180. p >>= 1;
  181.  
  182. if (p > 0)
  183. a *= a;
  184. }
  185.  
  186. return result;
  187. }
  188.  
  189. friend ostream &operator<<(ostream &os, const modular_int &m)
  190. {
  191. return os << m.val;
  192. }
  193. };
  194. template <const int &MOD>
  195. modular_int<MOD> modular_int<MOD>::save_inv[modular_int<MOD>::SAVE_INV];
  196. const int MOD = 998244353;
  197. using mint = modular_int<MOD>;
  198. void __print(mint x) { cerr << x; }
  199.  
  200. void solve(int tc)
  201. {
  202. int n;
  203. cin>>n;
  204. vector<int>ar(n+1);
  205. for(int i=1;i<=n;i++) cin>>ar[i];
  206. // coordinate compress 1-n
  207. vector<int>v=ar;
  208. sort(all(v));
  209. map<int,int>mp;
  210. int cur=1;
  211. for(int i=1;i<=n;i++)
  212. {
  213. if(mp.find(v[i])==mp.end())
  214. {
  215. mp[v[i]]=cur;
  216. v[i]=cur;
  217. cur++;
  218. }
  219. else
  220. {
  221. v[i]=mp[v[i]];
  222. }
  223. }
  224. for(int i=1;i<=n;i++) ar[i]=mp[ar[i]];
  225. vector<int>br,cr;
  226. auto getl=[&](vector<int>ar)
  227. {
  228. vector<int>vec;
  229. int prev=0;
  230. for(int i=1;i<=n;i++)
  231. {
  232. if(ar[i]>prev)
  233. {
  234. prev=ar[i];
  235. vec.push_back(ar[i]);
  236. }
  237. }
  238. return vec;
  239. };
  240. dbg(ar);
  241. br=getl(ar);
  242. reverse(ar.begin()+1,ar.end());
  243. cr=getl(ar);
  244. reverse(ar.begin()+1,ar.end());
  245. reverse(all(cr));
  246. for(int i=1;i<cr.size();i++)
  247. {
  248. br.push_back(cr[i]);
  249. }
  250. int m=br.size();
  251. br.insert(br.begin(),0);
  252. dbg(br);
  253. vector<vector<mint>>dp(n+1,vector<mint>(m+1,0));
  254. dp[0][0]=1;
  255. int idx=max_element(all(br))-br.begin(),mx=br[idx];
  256. dbg(idx,mx);
  257. for(int i=1;i<=n;i++)
  258. {
  259. for(int j=0;j<=m;j++)
  260. {
  261. //j < idx
  262. if(j<idx)
  263. {
  264. if(ar[i]<br[j]) dp[i][j]+=dp[i-1][j]*2; // either take or not take
  265. if(ar[i]>br[j]) dp[i][j]+=dp[i-1][j]; // not take
  266. if(ar[i]==br[j])
  267. {
  268. dp[i][j]+=dp[i-1][j]; // not take
  269. if(j)
  270. dp[i][j]+=dp[i-1][j-1]+dp[i-1][j];
  271. }
  272. }
  273. else if(j==idx)
  274. {
  275. if(ar[i]<br[j]) dp[i][j]+=dp[i-1][j]*2; // either take or not take
  276. if(ar[i]>br[j])
  277. {
  278. // dp[i][j]+=dp[i-1][j]; // not take
  279. //cant happen
  280. assert(0);
  281. }
  282. if(ar[i]==br[j])
  283. {
  284. dp[i][j]+=dp[i-1][j]; // not take
  285. if(j)
  286. dp[i][j]+=dp[i-1][j-1]+dp[i-1][j];
  287. }
  288. }
  289. else
  290. {
  291. if(ar[i]>br[j]) dp[i][j]+=dp[i-1][j]*2; // either take or not take
  292. if(ar[i]<br[j]) dp[i][j]+=dp[i-1][j]; // not take
  293. if(ar[i]==br[j])
  294. {
  295. dp[i][j]+=dp[i-1][j]; // not take
  296. if(j)
  297. dp[i][j]+=dp[i-1][j-1]+dp[i-1][j];;
  298. }
  299. }
  300. }
  301. }
  302. dbg(dp);
  303. cout<<dp[n][m]<<endl;
  304. }
  305. int32_t main()
  306. {
  307. #ifdef LOCAL1
  308. auto begin = std::chrono::high_resolution_clock::now();
  309. #endif
  310. ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
  311. int t=1;
  312. cin>>t;
  313. int tc=1;
  314. while (t--)
  315. {
  316. solve(tc),tc++;
  317. }
  318. #ifdef LOCAL1
  319. auto end = std::chrono::high_resolution_clock::now();
  320. cerr << setprecision(4) << fixed;
  321. cerr << "-> " << std::chrono::duration_cast<std::chrono::duration<double>>(end - begin).count() << " sec" << endl;
  322. #endif
  323. return 0;
  324. }
Advertisement
Add Comment
Please, Sign In to add comment