题意:对于整数序列$A[1...n]$定义$f(l, r)$为区间$[l, r]$内等于区间最大值元素的个数,定义$z[i]$为所有满足$f(l, r)=i$的区间总数。对于所有的$1 \leq i \leq n$,计算$z[i]$。

分析:考虑由大往小枚举最大值,对于某一最大值为$M$的区间$[l, r)$,满足$a[p_i]=M$的元素将区间切割为若干子区间,那么这些子区间对长度的积对答案的某一项有等值的贡献,暴力枚举需要$O(n^2)$的时间,整体考虑那些对答案某一项有贡献的子区间对的积,它们满足卷积的性质。因此只需将长度序列与其反序列作类似多项式乘法的fft,即可将时间优化为$O(nlog(n))$。子区间递归处理即可。代码如下:

  1. #include <algorithm>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <string>
  5. #include <queue>
  6. #include <map>
  7. #include <set>
  8. #include <stack>
  9. #include <ctime>
  10. #include <cmath>
  11. #include <iostream>
  12. #include <assert.h>
  13. #pragma comment(linker, "/STACK:102400000,102400000")
  14. #define max(a, b) ((a) > (b) ? (a) : (b))
  15. #define min(a, b) ((a) < (b) ? (a) : (b))
  16. #define mp std :: make_pair
  17. #define st first
  18. #define nd second
  19. #define keyn (root->ch[1]->ch[0])
  20. #define lson (u << 1)
  21. #define rson (u << 1 | 1)
  22. #define pii std :: pair<int, int>
  23. #define pll pair<ll, ll>
  24. #define pb push_back
  25. #define type(x) __typeof(x.begin())
  26. #define foreach(i, j) for(type(j)i = j.begin(); i != j.end(); i++)
  27. #define FOR(i, s, t) for(int i = (s); i <= (t); i++)
  28. #define ROF(i, t, s) for(int i = (t); i >= (s); i--)
  29. #define dbg(x) std::cout << x << std::endl
  30. #define dbg2(x, y) std::cout << x << " " << y << std::endl
  31. #define clr(x, i) memset(x, (i), sizeof(x))
  32. #define maximize(x, y) x = max((x), (y))
  33. #define minimize(x, y) x = min((x), (y))
  34. using namespace std;
  35. typedef long long ll;
  36. const int int_inf = 0x3f3f3f3f;
  37. const ll ll_inf = 0x3f3f3f3f3f3f3f3f;
  38. const int INT_INF = (int)((1ll << ) - );
  39. const double double_inf = 1e30;
  40. const double eps = 1e-;
  41. typedef unsigned long long ul;
  42. typedef unsigned int ui;
  43. inline int readint(){
  44. int x;
  45. scanf("%d", &x);
  46. return x;
  47. }
  48. inline int readstr(char *s){
  49. scanf("%s", s);
  50. return strlen(s);
  51. }
  52.  
  53. class cmpt{
  54. public:
  55. bool operator () (const int &x, const int &y) const{
  56. return x > y;
  57. }
  58. };
  59.  
  60. int Rand(int x, int o){
  61. //if o set, return [1, x], else return [0, x - 1]
  62. if(!x) return ;
  63. int tem = (int)((double)rand() / RAND_MAX * x) % x;
  64. return o ? tem + : tem;
  65. }
  66. void data_gen(){
  67. srand(time());
  68. freopen("in.txt", "w", stdout);
  69. int kases = ;
  70. printf("%d\n", kases);
  71. while(kases--){
  72. int sz = 6e4;
  73. printf("%d\n", sz);
  74. FOR(i, , sz) printf("%d ", Rand(sz, ));
  75. printf("\n");
  76. }
  77. }
  78.  
  79. struct cmpx{
  80. bool operator () (int x, int y) { return x > y; }
  81. };
  82. const int maxn = 6e4 + ;
  83. int a[maxn];
  84. int n;
  85. struct Seg{
  86. int l, r, v;
  87. }seg[maxn << ];
  88. void build(int u, int l, int r){
  89. seg[u].l = l, seg[u].r = r;
  90. if(seg[u].r - seg[u].l < ){
  91. seg[u].v = l;
  92. return;
  93. }
  94. int mid = (l + r) >> ;
  95. build(lson, l, mid), build(rson, mid, r);
  96. if(a[seg[rson].v] > a[seg[lson].v]) seg[u].v = seg[rson].v;
  97. else seg[u].v = seg[lson].v;
  98. }
  99. int query(int u, int l, int r){
  100. if(seg[u].l == l && seg[u].r == r) return seg[u].v;
  101. int mid = (seg[u].l + seg[u].r) >> ;
  102. if(r <= mid) return query(lson, l, r);
  103. else if(l >= mid) return query(rson, l, r);
  104. int lhs = query(lson, l, mid), rhs = query(rson, mid, r);
  105. if(a[rhs] > a[lhs]) return rhs;
  106. return lhs;
  107. }
  108. int maxi;
  109. vector<int> pos[maxn];
  110. int idx[maxn];
  111. void init(){
  112. maxi = -;
  113. FOR(i, , n) maximize(maxi, a[i]);
  114. FOR(i, , maxi) pos[i].clear();
  115. FOR(i, , n){
  116. int sz = pos[a[i]].size();
  117. idx[i] = sz;
  118. pos[a[i]].pb(i);
  119. }
  120. }
  121. ll z[maxn];
  122. ll c[maxn], d[maxn], e[maxn << ];
  123. int k;
  124. const double PI = * asin(.);
  125. struct Complex{
  126. double x, y;
  127. Complex(double x = , double y = ) : x(x), y(y) {}
  128. };
  129. Complex operator + (const Complex &lhs, const Complex &rhs){
  130. return Complex(lhs.x + rhs.x, lhs.y + rhs.y);
  131. }
  132. Complex operator - (const Complex &lhs, const Complex &rhs){
  133. return Complex(lhs.x - rhs.x, lhs.y - rhs.y);
  134. }
  135. Complex operator * (const Complex &lhs, const Complex &rhs){
  136. double tl = lhs.x * rhs.x, tr = lhs.y * rhs.y, tt = (lhs.x + lhs.y) * (rhs.x + rhs.y);
  137. return Complex(lhs.x * rhs.x - lhs.y * rhs.y, lhs.x * rhs.y + lhs.y * rhs.x);
  138. }
  139. Complex w[][maxn << ], x[maxn << ], y[maxn << ];
  140.  
  141. void fft(Complex x[], int k, int v){
  142. int i, j, l;
  143. Complex tem;
  144. for(i = j = ; i < k; i++){
  145. if(i > j) tem = x[i], x[i] = x[j], x[j] = tem;
  146. for(l = k >> ; (j ^= l) < l; l >>= ) ;
  147. }
  148. for(i = ; i <= k; i <<= ) for(j = ; j < k; j += i) for(l = ; l < i >> ; l++){
  149. tem = x[j + l + (i >> )] * w[v][k / i * l];
  150. x[j + l + (i >> )] = x[j + l] - tem;
  151. x[j + l] = x[j + l] + tem;
  152. }
  153. }
  154. int tot;
  155. void solve(int l, int r){
  156. if(l >= r) return;
  157. if(r - l == ){
  158. ++z[];
  159. return;
  160. }
  161. int p = query(, l, r);
  162. int tem = idx[p];
  163. int sz = pos[a[p]].size();
  164. k = ;
  165. c[k++] = p - l + ;
  166. while(tem + < sz && pos[a[p]][tem + ] < r) c[k++] = pos[a[p]][tem + ] - pos[a[p]][tem], ++tem;
  167. c[k++] = r - pos[a[p]][tem];
  168. ROF(i, k - , ) d[i] = c[k - - i];
  169. int len;
  170. for(len = ; len < (k << ); len <<= ) ;
  171. FOR(i, , len) w[][len - i] = w[][i] = Complex(cos(PI * * i / len), sin(PI * * i / len));
  172. FOR(i, , k - ) x[i] = Complex(c[i], );
  173. FOR(i, k, len - ) x[i] = Complex(, );
  174. fft(x, len, );
  175. FOR(i, , k - ) y[i] = Complex(d[i], );
  176. FOR(i, k, len - ) y[i] = Complex(, );
  177. fft(y, len, );
  178. FOR(i, , len - ) x[i] = x[i] * y[i];
  179. fft(x, len, );
  180. FOR(i, , * k - ) e[i] = (ll)(x[i].x / len + .);
  181. FOR(i, , k - ) z[k - - i] += e[i];
  182. tem = idx[p];
  183. solve(l, p);
  184. while(tem + < sz && pos[a[p]][tem + ] < r) solve(pos[a[p]][tem] + , pos[a[p]][tem + ]), ++tem;
  185. solve(pos[a[p]][tem] + , r);
  186. }
  187. int main(){
  188. //data_gen(); return 0;
  189. //C(); return 0;
  190. int debug = ;
  191. if(debug) freopen("in.txt", "r", stdin);
  192. //freopen("out.txt", "w", stdout);
  193. int T = readint();
  194. while(T--){
  195. n = readint();
  196. FOR(i, , n) a[i] = readint();
  197. build(, , n + );
  198. init();
  199. clr(z, );
  200. tot = ;
  201. solve(, n + );
  202. ll ans = ;
  203. FOR(i, , n) ans += z[i] ^ i;
  204. printf("%lld\n", ans);
  205. }
  206. return ;
  207. }

code:

hdu 5751 Eades的更多相关文章

  1. Fast Fourier Transform

    写在前面的.. 感觉自己是应该学点新东西了.. 所以就挖个大坑,去学FFT了.. FFT是个啥? 挖个大坑,以后再补.. 推荐去看黑书<算法导论>,讲的很详细 例题选讲 1.UOJ #34 ...

  2. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  4. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  5. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  6. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  7. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

  8. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

  9. HDU 3791二叉搜索树解题(解题报告)

    1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...

随机推荐

  1. Winform Combox DataSource 之不显示 displayemember 内容

    刚开始学习数据绑定的东西, private void Form1_Load(object sender, EventArgs e) { IList<TLayer> tt = new Lis ...

  2. SQL 参数化查询 应用于 Like

    在sql 进行参数化查询的时候,使用like 语句和参数的时候,错误的写法:  Participant like '%@Participant%' ,这样在数据库为解析为 '%'participant ...

  3. Rocky4.2下安装金仓v7数据库(KingbaseES)

    1.准备操作系统 1.1 系统登录界面 1.2 操作系统版本信息 jdbh:~ # uname -ra Linux jdbh -x86_64 # SMP Fri Dec :: CST x86_64 G ...

  4. 一篇很全面的freemarker教程

    以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成:1,文本:直接输出的部分2,注释:<#-- ... --& ...

  5. MySQL配置文件改变了datadir值

    从Noinstall Zip Archive中安装MySQL正在从Noinstall软件包安装MySQL的用户可以使用这个说明来手动安装MySQL.从Zip archive 中安装MySQL的 步骤如 ...

  6. P1073 最优贸易

    #include <bits/stdc++.h> using namespace std; const int maxn = 100005; int head1[maxn], head2[ ...

  7. Java Debug调试简单方法--static使用

    Public class Debug { public Debug() { } static void debugPrint(String src) { //System.out.print(src) ...

  8. Spark on YARN两种运行模式介绍

    本文出自:Spark on YARN两种运行模式介绍http://www.aboutyun.com/thread-12294-1-1.html(出处: about云开发)   问题导读 1.Spark ...

  9. iScroll.js和swiper.js

    最近系统地学习了iScroll.js和swiper.js,感觉它们在移动端特别好用:http://www.360doc.com/content/14/0724/11/16276861_39669990 ...

  10. Oracle中的rownum和rowid

    http://blog.csdn.net/mitedu/article/details/3584399  rownum http://blog.csdn.net/mitedu/article/deta ...