問題蟲洞: 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;
}