考虑同弦所对的圆周角相等,所以我们只需要先枚举一个点A,然后再枚举一个点B,计算∠ABO的大小,然后答案一定是组合数,算一下即可,不过这样存在一些方向上的问题,另一种做法就是先枚举两个点,计算这两个点与原点构成的圆的圆心,圆心的最大值一定是组合数,算一下即可得出答案,注意精度问题
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=44299374
int ans;
vectorv;
int main()
{
int n;
sc("%d", &n);
if (n == 1)
{
pr("1\n");
return 0;
}
Point oo = Point{ 0,0 };
for (int i = 1; i <= n; i++)
que[i].input();
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
{
if (sgn(cross(que[i], que[j], oo)) == 0)
continue;
circle o = circle{ oo, que[i], que[j] };
v.push_back(o.p);
}
}
sort(v.begin(), v.end());
int cnt = 0, len = v.size();
for (int i = 1; i < len; i++)
{
if (sgn(v[i].x - v[i - 1].x) == 0 && sgn(v[i].y - v[i - 1].y) == 0)
{
cnt++;
}
else
{
ans = max(ans, cnt);
cnt = 1;
}
}
ans = max(ans, cnt);
int res = 1;
while (res * (res - 1) / 2 != ans)
res++;
pr("%d\n", res);
}
一开始三个人讨论的时候,首先明确了连叶子结点,出来了一些接近答案的想法,然后无一例外,都被hack掉了,然后 jzk 提出了一个 dfs 序,然后也被 hack 掉了,然后 jzk 提出了左边一半连右边一半,多出来一个随便连,yp写了代码,过了
#include
using namespace std;
typedef long long ll;
const int MAX = 4e5+5;
const int INF = 0x3f3f3f3f;
int n,first[MAX],nextt[MAX],u[MAX],v[MAX],cnt,ans,du[MAX],dfn[MAX],tot;
vector list1;
void add(int a,int b){
u[cnt]=a,v[cnt]=b;
nextt[cnt]=first[u[cnt]];
first[u[cnt]]=cnt;++cnt;
}
void dfs(int dot,int fa){
dfn[dot]=++tot;
for(int num = first[dot];num!=-1;num=nextt[num]){
if(v[num]==fa) continue;
dfs(v[num],dot);
}
}
bool cmp(int a,int b){
return dfn[a]
由于 jzk 没注意到比赛开始了,所以5分钟的时候才签上到
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
int main()
{
int a, s, d, q, w, e;
sc("%d:%d:%d %d:%d:%d", &q, &w, &e, &a, &s, &d);
int ans1 = a * 3600 + s * 60 + d;
int ans2 = q * 3600 + w * 60 + e;
pr("%d\n", abs(ans1 - ans2));
}
有了一个快速沃尔什变换的板子,真香
题解给的做法是求出前19项即可,因为满秩的情况下最多18个数字异或最大,所以19的答案是不确定的,需要FWT求出答案,然后对于 n>=20 的答案 ans[n] = ans[n-2]
//https://ac.nowcoder.com/acm/contest/5667/E
//异或卷积 选1-n个数字,异或值最大,可重复选
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const ll mod = 1e9 + 7;
const ll inv2 = (mod + 1) / 2;
const int MAXN = (3e5 + 5) * 2;//最大值的两倍(fwt一倍空间也可?)
ll a[MAXN];
ll s[MAXN];
ll ans[MAXN];
void FWT_or(ll a[], int len, int opt)
{
for (int i = 1; i < len; i <<= 1)
for (int p = i << 1, j = 0; j < len; j += p)
for (int k = 0; k < i; ++k)
if (opt == 1)
a[i + j + k] = (a[j + k] + a[i + j + k]) % mod;
else
a[i + j + k] = (a[i + j + k] + mod - a[j + k]) % mod;
}
void FWT_and(ll a[], int len, int opt)
{
for (int i = 1; i < len; i <<= 1)
for (int p = i << 1, j = 0; j < len; j += p)
for (int k = 0; k < i; ++k)
if (opt == 1)
a[j + k] = (a[j + k] + a[i + j + k]) % mod;
else
a[j + k] = (a[j + k] + mod - a[i + j + k]) % mod;
}
void FWT_xor(ll a[], int len, int opt)
{
for (int i = 1; i < len; i <<= 1)
for (int p = i << 1, j = 0; j < len; j += p)
for (int k = 0; k < i; ++k)
{
ll x = a[j + k], y = a[i + j + k];
a[j + k] = (x + y) % mod;
a[i + j + k] = (x + mod - y) % mod;
if (opt == -1)
{
a[j + k] = 1ll * a[j + k] * inv2 % mod;
a[i + j + k] = 1ll * a[i + j + k] * inv2 % mod;
}
}
}
void FWT(ll a[], int len, int opt)
{
for (int i = 1; i < len; i <<= 1)
for (int p = i << 1, j = 0; j < len; j += p)
for (int k = 0; k < i; ++k)
{
ll x = a[j + k], y = a[i + j + k];
a[j + k] = (x + y);//% mod;
a[i + j + k] = (x - y);//% mod;
if (opt == -1)
{
a[j + k] = 1ll * a[j + k] / 2;// *inv2% mod;
a[i + j + k] = 1ll * a[i + j + k] / 2;// *inv2% mod;
}
}
}
void run(ll a[], ll b[], int len1, int len2)
{
FWT(a, len1, 1);
FWT(b, len2, 1);
int lens = 1;//最大长度的两倍(fwt一倍也可?)
while (lens < 2 * len1 || lens < 2 * len2)
lens <<= 1;
for (int i = 0; i < lens; i++)
a[i] = a[i] * b[i];
FWT(a, len1, -1);
FWT(b, len2, -1);
}
int main()
{
int n;
sc("%d", &n);
for (int i = 0; i < n; i++)
{
ll t;
sc("%lld", &t);
a[t] = 1;
s[t] = 1;
ans[1] = max(ans[1], t * 1LL);
}
for (int i = 2; i <= min(19, n); i++)
{
run(s, a, 1 << 18, 1 << 18);
for (int j = 0; j < MAXN; j++)
{
if (s[j])
{
ans[i] = max(ans[i], j * 1LL);
s[j] = 1;
}
}
}
for (int i = min(19, n) + 1; i <= n; i++)
ans[i] = ans[i - 2];
for (int i = 1; i <= n; i++)
pr("%lld%c", ans[i], i == n ? '\n' : ' ');
}
开场 jzk 看了一眼,然后感觉不太可做,然后 dh 说直接单调队列扫两次就完了,然后 jzk 恍然大悟,卡了一下空间就A了,有一个问题,题解给了一个筛法求gcd,赛时的时候 jzk 也想到用筛法来优化 gcd,由于太菜写了错误的筛法,贡献了一发罚时
不过出题人给的筛法还是很nb的
#include
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
int matrix[5005][5005];
int temp1[5005][5005];
int main()
{
int n, m, k;
sc("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (temp1[i][j] == 0) {
for (int k = 1; k * i <= n && k * j <= m; k++) {
temp1[i * k][j * k] = k;
}
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
matrix[i][j] = i * j / temp1[i][j];
}
}
for (int i = 1; i <= n; i++)
{
dequeq;
for (int j = 1; j <= m; j++)
{
while (!q.empty() && matrix[i][q.back()] < matrix[i][j])
q.pop_back();
while (!q.empty() && j - q.front() + 1 > k)
q.pop_front();
q.push_back(j);
if (j >= k)
temp1[i][j - k + 1] = matrix[i][q.front()];
}
}
//n m-k+1
for (int j = 1; j <= m - k + 1; j++)
{
dequeq;
for (int i = 1; i <= n; i++)
{
while (!q.empty() && temp1[q.back()][j] < temp1[i][j])
q.pop_back();
while (!q.empty() && i - q.front() + 1 > k)
q.pop_front();
q.push_back(i);
if (i >= k)
matrix[i - k + 1][j] = temp1[q.front()][j];
}
}
//n-k+1 m-k+1
ll ans = 0;
for (int i = 1; i <= n - k + 1; i++)
{
for (int j = 1; j <= m - k + 1; j++)
ans += 0LL + matrix[i][j];
}
pr("%lld\n", ans);
}
学习自 https://www.cnblogs.com/wlzhouzhuan/p/13301358.html
大概做法就是固定点 A 在(1,0)上,然后考虑若 B 点确定,则可以积分求出点 C 到直线 AB 之间的距离,然后由于题目要求的精度要求比较小,所以可以考虑枚举 B 的位置,就是在 B 所在的圆中,等距离取若干个点,他们的平均值作为点 C 到直线 AB 之间的距离,然后面积就等于高度乘以底/2。
感觉难度大概在将整个图建模出来,和如何求出点 C 到直线 AB 之间的距离。
#include
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const double PI = acos(-1.0);
int main()
{
int T;
sc("%d", &T);
while (T--)
{
int r[3];
sc("%d%d%d", &r[0], &r[1], &r[2]);
sort(r, r + 3);
double ans = 0;
for (int i = 1; i <= 1000; i++)
{
double x = r[1] * cos(2 * PI / 1000 * i);
double y = r[1] * sin(2 * PI / 1000 * i);
double L = sqrt((x - r[0]) * (x - r[0]) + y * y);
double H = y / L * r[0];
double angle = asin(H / r[2]);
double h = 4.0 * r[2] * (angle * sin(angle) + cos(angle)) / (2 * PI);
ans += h * L / 2;
}
ans /= 1000.0;
printf("%.1f\n", ans);
}
}