Learn a new posture. (I can't read the code card for a long time t t
First, the number range is so small, you can consider enumerating the majority to calculate the answer, set the current enumeration to $x$, $s _i$ is the number of $x$ in the previous $i$ number of occurrences, then the $2*s_r-r > 2*s_l-l$ of the interval $[l+1,r]$ the majority of $x$, This can obviously be maintained with a data structure.
The direct sweep efficiency is $o ($ number Kind number $*nlogn) $, unbearable, but we found that for each non-$x$ number, $2*s_i-i$ is the $-1$ of tolerance arithmetic progression, so their contribution to the answer can actually be calculated once. Set $l$ to the beginning of a non-$x$ number, $R $ for the end, then $\leq 2*s_r-r$ the number of contributions will be calculated $len$ times, $2*s_{r-1}-(R-1) $ number of contributions will be calculated $len-1$ times, ..., $s _l-l$ the contribution of the number will be calculated $1$ Times, the number of calculations for this contribution is also a arithmetic progression.
Well, we actually have three ways to maintain this.
① Maintenance $a_i$ represents the number of occurrences of $2*s_i-i$, supports interval plus and interval queries $\sum_{i=l}^r a_i* (i-l+1) $, more cumbersome, weighted segment tree.
② Maintenance $s_i$ represents $a_i$ prefix and, support interval plus a section of arithmetic progression and interval query, can write, weight value line segment tree.
③ Maintenance $s_i$ prefix and, support interval plus two functions and single point query, code short but because of the more abstract so some difficult to tune, tree-like array, very fast.
This is only the third way of writing, the first time to see this operation ...
The tree array actually maintains the $s_1,s_1+s_2,s_1+s_2+s_3,... $, so when modifying an interval, it is equivalent to adding a arithmetic progression sum to a section, i.e. $ ((1+i-l+1) * (i-l+1))/2= (i^2+ (3-2l) i+l ^2+3l+2)/2$, so we just need to maintain two items on a tree-like array, a term and a constant term, interval modification with the difference, the last query for a period of time as long as the end of the subtraction is good ...
#include <iostream>#include<cstring>#include<cstdlib>#include<cstdio>#definell Long Longusing namespacestd;Const intmaxn=1000010;intN, x, N, t;intA[MAXN], TREETY[MAXN], POS[MAXN], Pre[maxn];ll TREE1[MAXN], TREE2[MAXN], Tree3[maxn], ans;Charbuf[20000010],*ptr=buf-1; inlineintRead () {CharC=*++ptr;ints=0, t=1; while(c< -|| C> $) c=*++ptr; while(c>= -&&c<= $) {s=s*Ten+c-'0'; c=*++ptr;} returns*T;} InlinevoidAddintXintp) {x+=n+1; ll Delta1=1, delta2=3-2*x, delta3=1ll*x*x-3*x+2; for(; x<=n;x+=x&-x) {if(treety[x]!=t) treety[x]=t, tree1[x]=tree2[x]=tree3[x]=0; TREE1[X]+=delta1*p, Tree2[x]+=delta2*p, tree3[x]+=delta3*p; }}inlinevoidQueryintXintty) {x+=n+1;intpos=x; for(; x;x-=x&-x)if(treety[x]==t) ans+ = (Tree1[x]*pos*pos+tree2[x]*pos+tree3[x]) *Ty;} InlinevoidUpdateintLintRints) {Add (2*s-r,1); Add2*s-l+1, -1);}intMain () {fread (buf,1,sizeof(BUF), stdin); N=read (); X=read (); n=n+n+2; for(intI=1; i<=n;i++) X=read (), pre[i]=pos[x], pos[x]=i; for(intI=0; i<n;i++) if(Pos[i]) {intCnt=0; ++T; for(intJ=POS[I];J;J=PRE[J]) a[++cnt]=J; Update (0, a[cnt]-1,0); for(intj=cnt;j;j--) {Query (2* (cnt-j+1)-a[j]-1,1); Query (2* (cnt-j+1)-((J1)? a[j-1]+1: n+2), -1); Update (A[j], (J-1)? a[j-1]-1: N, cnt-j+1); }} printf ("%lld\n", ans>>1);}
View Code
"codeplus 2017 November"yazid's freshman Prom (tree array/Line tree)