问题虫洞: B - Uniqueness CodeForces - 1208B
黑洞内窥:
给出n个数,求一个最小区间的个数,
该最小区间满足在该序列删除了这个最小区间后,元素无重复
思维光年:
双map维护左右端点。。。
ACcode:
#include<stdio.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
#define MAXN 10025
#define INF 0x3f3f3f3f//将近int类型最大数的一半,而且乘2不会爆int
#define MOD 1000000007 // MOD%4 = 3
const double pi = acos(-1.0);
const double eps = 1e-6;
map<int, int>m1, m2;
int a[MAXN];
int main()
{
int n;
scanf("%d", &n);
for(int i=1; i<=n; ++i)
scanf("%d", &a[i]);
int p=1, q=n; //左右扫描
while(p<=n) //先找出左区间不同元素的最右端的位置
{
if(m1[a[p]]) break;
else m1[a[p]] = p; //标记下标
p++;
}
p--;
int ans = n-p; //最小区间大小
while(q>=1)
{
if(m2[a[q]])
{
if(ans > q-p) ans = q-p;
break;
}
else m2[a[q]] = 1;
if(m1[a[q]] && p>=m1[a[q]]) //如果右区间左端点的元素出现在了左区间
{
if(ans > q-p) ans = q-p;
p = m1[a[q]] - 1; //左区间往回退
}
q--;
}
cout << ans << '\n';
return 0;
}
问题虫洞: G - Polygons CodeForces - 1208G
黑洞内窥:
输入n和k,求在单位圆中需要最小多少个点可以放进去k个多边形,
且多边形不能超过n多边形。。
思维光年:
不成熟的思考(老师在讲课,我™没带耳塞。。):
每一个多边形都可以至少有一点重合在单位圆的正上方的位置(我们记作0),
而一个正m边形是覆盖掉了所有的d|m的正d边形的所有点,,,
所以,可以暴力出所有的正m边形,然后排序取前k个相加,,,
重要的是,我居然没有敲出来,,,更重要的是,我没想到欧拉函数。。。。。
理性的求解:
我们在选正多边形时,可以使每一个正多边形的第一个点重合。
那么正m边形的每一个点在圆上的位置就可以表示为0,1/m,2/m,...,m−1/m。
因此在选择了k个正多边形后,最简真分数的总数即为我们要求的答案。
于是只需要将我们选择的k个正多边形的欧拉函数累加即为答案,
因为欧拉函数就是互质数数量,也就是新增加的点数。
ACcode:
#include<stdio.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
#define MAXN 1000025
#define INF 0x3f3f3f3f//将近int类型最大数的一半,而且乘2不会爆int
#define MOD 1000000007 // MOD%4 = 3
const double pi = acos(-1.0);
const double eps = 1e-6;
int phi[MAXN];
void init()
{
phi[1] = 1;
for(int i=2; i<MAXN; ++i)
{
if(!phi[i])
{
for(int j=i; j<MAXN; j+=i)
{
if(!phi[j]) phi[j] = j;
phi[j] = phi[j]/i*(i-1);
}
}
}
}
int main()
{
init();
int n, k;
ll sum=0;
cin >> n >> k;
if(k == 1) puts("3"); //一个的话只能选三角形了。。
else {
sort(phi+3, phi+n+1);
for(int i=0; i<k; ++i)
sum+=phi[3+i];
cout << sum+2 << '\n'; //+2是因为三角形还有另外两个点。。
}
return 0;
}