下面是我要解决,我使用的事实,问题是preFIX总和[I] - preFIX总和[I-1]
导致频率为大于零,以确定鲜明的数字,然后我消除了频率,但即使有位,我得到一个TLE
鉴于正数A1的序列,A2,...,an和一数目的d查询。
一个D-查询是一对(I,J)(1≤I≤Ĵ≤N)。
有关各d查询(I,J),则必须返回在子序列艾不同元件的数量,AI + 1,...,AJ。
输入
线路1:N(1≤N≤30000)。
线路2:N号A1,A2,...,一(1≤艾≤106)。
线3:Q(1≤q≤200000)中,d-查询的数量。
在下一q行,每行包含2号I,J
再presenting一个D-查询(1≤I≤Ĵ≤N)。
输出
对于每一个的d查询(I,J),打印时,在不同的元素数
子AI,AI + 1,...,AJ在一行。
例
输入
五
1 1 2 1 3
3
1 5
2 4
3 5
输出
3
2
3
在code是:
的#include<的iostream>
#包括<算法>
#包括<载体>
#包括< stdlib.h中>
#包括< stdio.h中>
长期的typedef长整型LL;
使用名字空间std;
无效更新(LL N,LL VAL,矢量< LL>和b);
LL阅读(LL N,矢量< LL>和b);
LL readsingle(LL N,矢量< LL>和b);
空隙地图(矢量< LL>&安培;一,矢量< LL>和b,LL n)的/ ****相对映射*** /
{
LL温度;
a.clear();
b.clear();
对于(LL我= 0;我n种;我++)
{
CIN>>温度;
a.push_back(临时);
b.push_back(临时);
}
排序(b.begin(),b.end());
对于(LL我= 0;我n种;我++)
*(a.begin()+ I)=(LOWER_BOUND(b.begin(),b.end(),A [1]) - b.begin())+ 1;
b.assign(N + 1,0);
}
诠释的main()
{
LL N;
霉素>将N;
矢量< LL>的a,b;
图(A,B,n)的;
LL吨;
CIN>>吨;
而(T--)
{
LL L,U;
b.assign(N + 1,0);
CIN>> L>> U;
L - ; / ***减少从零开始的索引**** /
u--;
对于(LL其中i = 1; I< = U;我++)
更新(A [1],1,b)条;
LL CONT = 0;
对于(LL其中i = 1; I< = U;我++)
如果(readsingle(A [1],B)大于0)
{
续++;
更新(A [1], - readsingle(A [1],b)中,二); / ***消除频率* /
}
COUT<<续<< ENDL;
}
返回0;
}
LL readsingle(LL N,矢量< LL>和b)
{
返回读取(N,B)-read第(n-1,B);
}
LL阅读(LL N,矢量< LL>和b)
{
LL总和= 0;
为(N;总和+ = B [N],正= N&安培; -n);
返回总和;
}
无效更新(LL N,LL VAL,矢量< LL>和b)
{
对于(; N< = b.size(); B [N] + = VAL,N + = N&安培; -n);
}
解决方案
您使用的算法是太慢了。对于每个查询,您遍历整个查询范围,这已经给ñ* Q
操作(很明显,这是太多)。这里是一个更好的解决方案(它有 O((N + Q)* log n)的
时间和 O(N + Q)
空间复杂度(这是一个离线解决方案):
让我们通过他们的右端的所有查询排序(没有必要明确地对它们进行排序,你可以查询只需添加到一个合适的位置(距离 0
以 N - 1
))
现在让我们遍历所有位置的数组中从左至右,保持一点。在BIT每个位置可以是 1
(这意味着在位置一个新的元素我
)或者 0
(最初,它充满了零)。
对于每一个元素 A [1]
:如果此元素的第一次出现,只需添加一个到我
在位的位置。否则, 1
添加到这个元素previous出现的位置,然后添加 1
的我
位置。
这个问题的答案查询(左,右)
只是总和的所有元素从离开
以右键
。
要保持每个元素的最后出现,你可以使用地图。
这是可能使用持久段树(时间复杂度是一样的,同样的复杂性将成为 0,使其在线(N *日志中n + q)
),但它并不需要在这里。
Here is The Problem i Want to Solve , I am Using The Fact That Prefix Sum[i] - Prefix Sum[i-1]
Leads to Frequency being Greater than Zero to Identify Distinct Digits and Then i am Eliminating The Frequency , But Even with BIT , i am Getting a TLE
Given a sequence of n numbers a1, a2, ..., an and a number of d-queries.
A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n).
For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.
Input
Line 1: n (1 ≤ n ≤ 30000).
Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
In the next q lines, each line contains 2 numbers i, j
representing a d-query (1 ≤ i ≤ j ≤ n).
Output
For each d-query (i, j), print the number of distinct elements in the
subsequence ai, ai+1, ..., aj in a single line.
Example
Input
5
1 1 2 1 3
3
1 5
2 4
3 5
Output
3
2
3
the code is:
#include <iostream>
#include <algorithm>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
typedef long long int ll;
using namespace std;
void update(ll n, ll val, vector<ll> &b);
ll read(ll n,vector<ll> &b);
ll readsingle(ll n,vector<ll> &b);
void map(vector<ll> &a,vector<ll> &b,ll n) /**** RElative Mapping ***/
{
ll temp;
a.clear();
b.clear();
for(ll i=0; i<n; i++)
{
cin>>temp;
a.push_back(temp);
b.push_back(temp);
}
sort(b.begin(),b.end());
for(ll i=0; i<n; i++)
*(a.begin()+i) = (lower_bound(b.begin(),b.end(),a[i])-b.begin())+1;
b.assign(n+1,0);
}
int main()
{
ll n;
cin>>n;
vector<ll> a,b;
map(a,b,n);
ll t;
cin>>t;
while(t--)
{
ll l ,u;
b.assign(n+1,0);
cin>>l>>u;
l--;/*** Reduce For Zero Based INdex ****/
u--;
for(ll i=l;i<=u;i++)
update(a[i],1,b);
ll cont=0;
for(ll i=l;i<=u;i++)
if(readsingle(a[i],b)>0)
{
cont++;
update(a[i],-readsingle(a[i],b),b); /***Eliminate The Frequency */
}
cout<<cont<<endl;
}
return 0;
}
ll readsingle(ll n,vector<ll> &b)
{
return read(n,b)-read(n-1,b);
}
ll read(ll n,vector<ll> &b)
{
ll sum=0;
for(; n; sum+=b[n],n-=n&-n);
return sum;
}
void update(ll n, ll val, vector<ll> &b)
{
for(; n<=b.size(); b[n]+=val,n+=n&-n);
}
解决方案
The algorithm you use is too slow. For each query, your iterate over the entire query range, which already gives n * q
operations(obviously, it is way too much). Here is a better solution(it has O((n + q) * log n)
time and O(n + q)
space complexity (it is an offline solution):
Let's sort all queries by their right end(there is no need to sort them explicitly, you can just add a query to an appropriate position (from 0
to n - 1
)).
Now let's iterate over all positions in the array from left to right and maintain a BIT. Each position in the BIT is either 1
(it means that there is a new element at position i
) or 0
(initially, it is filled with zeros).
For each element a[i]
: if it the first occurrence of this element, just add one to the i
position in the BIT. Otherwise, add -1
to the position of the previous occurrence of this element and then add 1
to the i
position.
The answer to the query (left, right)
is just sum for all elements from left
to right
.
To maintain the last occurrence of each element, you can use a map.
It is possible to make it online using persistent segment tree(the time complexity would be the same, the same complexity would become O(n * log n + q)
), but it is not required here.