学生作业网站,seo资源网,设计商标logo用什么软件,广东品牌网站建设Problem - C - Codeforces
题目大意#xff1a;有一个长度为n的数组a#xff0c;问有多少个子串[l,r]#xff0c;满足这个子串作为子序列只在a中出现过一次
1n1e5;1a[i]1e9
思路#xff1a;我们发现对于从1开始的连续区间#xff0c;答案都是非递减的有一个长度为n的数组a问有多少个子串[l,r]满足这个子串作为子序列只在a中出现过一次
1n1e5;1a[i]1e9
思路我们发现对于从1开始的连续区间答案都是非递减的所以我们考察每添加一个数字答案怎么变化并不会影响前面的答案。 那么假如我们当前新添了一个数a[r]那么新增的合法答案计数就是a[r]为区间右端点的合法子串也就是看1到r中有多少个l满足[l,r]是合法区间我们发现对于前面的一个数a[i]如果它出现了多次那么只有第一次出现时作为区间左端点才是合法的在后面出现时那个数都可以被第一次出现的那个数替代所以每个位置的数的贡献也就是在它前面第一次出现的数的数量那么每个相同的数的贡献也就是在最后出现的那个位置之前有多少第一次出现的数。 要统计答案我们首先记录每个数最后一次出现的位置las[i]然后从左往右遍历数组记录第一次出现的数的数量然后如果当前数已经在这个数最后一次出现的位置就统计这个数的贡献。
//#include__msvc_all_public_headers.hpp
#includebits/stdc.h
using namespace std;
typedef long long ll;
const ll MOD 1e9 7;
const int N 1e5 5;
int n;
int a[N];
void init()
{}
void solve()
{mapint, intlas;cin n;init();for (int i 1; i n; i){cin a[i];las[a[i]] i;//记录每个数字最后一次出现的次数}ll ans 0;ll cnt 0;setintvis;for (int i 1; i n; i){ if (vis.find(a[i]) vis.end()){//第一次出现这个数字cnt;//记录有多少个第一次出现的vis.insert(a[i]);}if (las[a[i]] i){//当前数字是最后一次出现的位置统计贡献ans cnt;}}cout ans;cout \n;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int t;cin t;//t 1;while (t--){solve();}return 0;
}