題目要求求某段區間第乙個沒有出現的數(0,1,2,3.。。。) ,對於所有的區間,我們把這樣的數加起來最後得到乙個結果。
首先,我們要求出這樣的數,然後還得列舉出所有的區間,複雜度太大了。
換種思路,我們定住l,是不是一次效能求出所有的r所得出的結果,這就用到線段樹的性質了,因為在移動l的過程中,移一步只變化乙個數,那麼就可以用線段樹進行維護。
首先求出[1,r] 以1為左端的所有區間的情況,記錄每個點也就是1到那個點的這段區間值sum[i],以這個值建一顆樹,那麼在l向前移動的時候,每次丟掉乙個數a[i-1], 因為少了這乙個數,肯定後面有部分區間是變化的,有部分是不變化的,從這點開始向後找第乙個與a[i-1]值相等的數的位置p,那麼這個位置後面的sum肯定不會變化,因為丟掉的數又補上了。
那麼就可以只考慮,從i位置到p這段裡面的sum,如果原先的sum本來就比a[i-1]小,那說明a[i-1]的減少不影響它的值,所以不用改變,而所有大於a[i-1]的值將都變為a[i-1],這樣更新一下,求和就可以了。
1 #include 2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #includeview code10 #include11
using
namespace
std;
12//
#pragma comment(linker, "/stack:1024000000,1024000000")
13#define n 200010
14#define ll __int64
15#define inf 0xfffffff
16const
double eps = 1e-8;17
const
double pi = acos(-1.0
);18
const
double inf = ~0u>>2
;19 vectorpo[n];
20 mapf;
21 ll s[n<<2
];22
int tm[n<<2
];23 ll lz[n<<2
];24
intsum[n];
25int
p[n],a[n];
26bool
vis[n];
27void up(int
w)28
33void down(int w,int
m)3444}
45void build(int l,int r,int
w)46
53int m = (l+r)>>1
;54 build(l,m,w<<1
);55 build(m+1,r,w<<1|1
);56
up(w);57}
58void update(int a,int b,int d,int l,int r,int
w)59
68int m = (l+r)>>1
;69 down(w,r-l+1
);70
if(a<=m) update(a,b,d,l,m,w<<1
);71
if(b>m) update(a,b,d,m+1,r,w<<1|1
);72
up(w);73}
74int find(int k,int l,int r,int
w)75
82int m = (l+r)>>1
;83 down(w,r-l+1
);84
if(tm[w<<1]>k)
85return find(k,l,m,w<<1
);86
else
87return find(k,m+1,r,w<<1|1
);88
}89 ll query(int a,int b,int l,int r,int
w)90
95int m = (l+r)>>1
;96 ll res = 0
;97 down(w,r-l+1
);98
if(a<=m)
99 res+=query(a,b,l,m,w<<1
);100
if(b>m)
101 res+=query(a,b,m+1,r,w<<1|1
);102
return
res;
103}
104int
main()
105122
int o = 0
;123
for(i = 1; i <= n ; i++)
124135
}136 ll ans=0
;137 build(1,n,1
);138 ans+=s[1
];139
//cout<140 p[f[a[1]]] = 1
;141
for(i = 2; i <= n ; i++)
142151
else k =n;
152 update(1,i-1,0,1,n,1
);153
intfk;
154if(tm[1]>a[i-1
])155
159 ans+=query(i,n,1,n,1
);160
//cout<161
//cout<162
//cout<163
//if(a[i]!=a[i-1])
164 p[f[a[i]]]++;
165}
166 cout
167}
168return0;
169 }
區間MEX 線段樹維護mex陣列
問題描述 給你乙個長度為n的數列,元素編號1到n,第i個元素值為ai。現在有m個形如 l,r 的提問,你需要回答出區間 l,r 的mex值。即求出區間 l,r 中沒有出現過的最小的非負整數。輸入格式 第一行,兩個整數n和m 第二行,n個空格間隔的整數,表示數列a 接下來m行,每行兩個整數l,r,表示...
mex(線段樹 離散化)
題目描述 給你乙個無限長的陣列,初始的時候都為0,有3種操作 操作1是把給定區間 l,r l,r l,r 設為1,操作2是把給定區間 l,r l,r l,r 設為0,操作3把給定區間 l,r l,r l,r 0,1反轉。l r 一共n個操作,每次操作後要輸出最小位置的0。l,r 題解 l r 經過分...
poj Buy Tickets 巧妙的線段樹
做完這道題才意識到什麼是線段樹的巧妙運用。yy才是王道啊!include define maxn 200050 define lson l m rt 2 define rson m 1 r rt 2 1 int n int rest maxn 4 ans maxn int id maxn value...