title :2022牛客暑期多校训练营4 题解
date : 2022-8-18
tags : ACM,练习记录
author : Linno
2022牛客暑期多校训练营4 题解
题目链接 :https://ac.nowcoder.com/acm/contest/33189
补题进度 :9/14
私信提醒我补题QAQ
A - Task Computing
排序不等式, ∑ i = 1 m w a i ∏ j i − 1 p a j \sum_{i=1}^m w_{a_i}\prod_j^{i-1}p_{a_j} ∑i=1mwai∏ji−1paj求最大收益。将 w [ i ] / ( 10000 − q [ i ] ) w[i]/(10000-q[i]) w[i]/(10000−q[i])大的结点排在前面。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
struct node{
int w,q;
}s[N];
bool cmp(node A,node B){
return A.w*(10000ll-B.q)>B.w*(10000ll-A.q);
}
int n,m;
double dp[25];
void Solve(){
cin>>n>>m;
for(int i=1;i<=n;++i) cin>>s[i].w;
for(int i=1;i<=n;++i) cin>>s[i].q;
sort(s+1,s+1+n,cmp);
for(int i=n;i>=1;i--){
for(int j=m-1;j>=0;--j){
dp[j+1]=max(dp[j+1],dp[j]*0.0001*s[i].q+s[i].w);
}
}
printf("%.15lf",dp[m]);
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
// cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;
return 0;
}
B - 2D Internet Angel
C - Easy Counting Problem
#include <bits/stdc++.h>
using namespace std;
const int N = 1<<18;
const int P = 998244353;
typedef vector<int> vi;
inline int add(int a, int b) { int r = a + b; return r < P ? r : r - P; }
inline int sub(int a, int b) { int r = a - b; return r < 0 ? r + P : r; }
inline int mul(int a, int b) { return 1ll * a * b % P; }
inline int qpm(int a, int b) {
int r = 1;
do if (b & 1) r = mul(r, a);
while (a = mul(a, a), b >>= 1);
return r;
}
inline int inv(int x) { return qpm(x, P - 2); }
namespace NTT1 {
using ::mul;
using ::inv;
const int W = 18, S = 1 << W, g = 3;
int w[S + 1], rev[S << 1], *r[W + 1];
void init() {
for (int s = 0; s <= W&&(r[s]=rev+(1<<s),1); ++s)
for (int i = 0; i != (1 << s); ++i)
r[s][i] = (r[s][i >> 1] >> 1) | ((i & 1) << (s - 1));
w[0] = 1; w[1] = qpm(g, (P - 1) / S);
for (int i = 2; i <= S; ++i) w[i] = mul(w[i - 1], w[1]);
}
int m, s, im;
int init(int n) {
for (s = 0, m = 1; m < n; m <<= 1, ++s);
im = inv(m); return m;
}
void ntt(int* p, const int t) {
for (int i = 0; i != m; ++i) if (i < r[s][i]) swap(p[i], p[r[s][i]]);
for (int i = 1, z = 0; i != m; i <<= 1, z++)
for (int j = 0; j != m; j += (i << 1))
for (int k = 0, u, v; k != i; k++)
u = p[j+k], v = mul(w[(t?(i<<1)-k:k)<<W-z-1], p[i+j+k]),
p[j + k] = add(u, v), p[i + j + k] = sub(u, v);
if (t) for (int i = 0; i != m; ++i) p[i] = mul(p[i], im);
}
int px[S], py[S];
vi pmul(const vi& p1, const vi& p2, int n = 0) {
int n1 = p1.size(), n2 = p2.size(), n3 = n1 + n2 - 1;
init(n3);
copy_n(p1.begin(), n1, px); fill(px + n1, px + m, 0);
copy_n(p2.begin(), n2, py); fill(py + n2, py + m, 0);
ntt(px, 0); ntt(py, 0);
for (int i = 0; i != m; ++i) px[i] = mul(px[i], py[i]);
ntt(px, 1); vi p3(n3); copy_n(px, n3, p3.begin());
if (n && n3 > n) p3.resize(n); return p3;
}
vi pinv(const vi& p1) {
int n1 = p1.size(), n2 = (n1 + 1) >> 1;
if (n1 == 1) return { inv(p1[0]) };
else {
vi p2 = pinv(vi(p1.begin(), p1.begin() + n2));
init(n1 << 1);
copy_n(p1.begin(), n1, px); fill(px + n1, px + m, 0);
copy_n(p2.begin(), n2, py); fill(py + n2, py + m, 0);
ntt(px, 0); ntt(py, 0);
for (int i = 0; i != m; ++i)
px[i] = mul(sub(2, mul(px[i], py[i])), py[i]);
ntt(px, 1); vi p3(n1); copy_n(px, n1, p3.begin());
return p3;
}
}
}
using NTT1::init;
using NTT1::pmul;
using NTT1::pinv;
vi padd(const vi& p1, const vi& p2) {
int n3 = max(p1.size(), p2.size());
vi pr = p1; pr.resize(n3, 0);
for (int i = 0; i != p2.size(); ++i) pr[i] = add(pr[i], p2[i]);
return pr;
}
vi psub(const vi& p1, const vi& p2) {
int n3 = max(p1.size(), p2.size());
vi pr = p1; pr.resize(n3, 0);
for (int i = 0; i != p2.size(); ++i) pr[i] = sub(pr[i], p2[i]);
return pr;
}
const int M = 10000001;
int invs[M], fac[M], ifac[M];
int binom(int n, int k) { return mul(fac[n], mul(ifac[n - k], ifac[k])); }
void ginv() {
invs[1] = 1; fac[0] = ifac[0] = 1;
for (int i = 2; i != M; ++i) invs[i] = mul(invs[P % i], (P - P / i));
for (int i = 1; i != M; ++i) fac[i] = mul(fac[i - 1], i);
for (int i = 1; i != M; ++i) ifac[i] = mul(ifac[i - 1], invs[i]);
}
int main(void) {
ginv();
init();
int w; scanf("%d", &w);
vector<int> c(w);
for (int& e : c) scanf("%d", &e);
int s = 0;
for (int e : c) s += e;
vector<vi> g(1, vi(1, 1));
for (int e : c) {
vi f(ifac, ifac + e);
vector<vi> tmp;
tmp.push_back(vi(1, 0));
for (int i = 0; i < (int)g.size(); ++i) {
tmp[i] = psub(tmp[i], pmul(g[i], f));
tmp.push_back(move(g[i]));
}
g = move(tmp);
}
int q; scanf("%d", &q);
while (q--) {
int n; scanf("%d", &n);
int ans = 0;
for (int i = 0; i <= w; ++i) {
int u = min(n, (int)g[i].size() - 1);
int z = qpm(i, n - u);
for (int j = u; j >= 0; --j) {
ans = add(ans, mul(mul(z, ifac[n - j]), g[i][j]));
z = mul(z, i);
}
}
printf("%d\n", mul(ans, fac[n]));
}
return 0;
}
D - Jobs (Easy Version)
随机种子要放在询问前面,不知道有多少人像我一样在这里wa了一发。开个三维数组直接记录最小值,然后做dp即可。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 405
//#define int long long
using namespace std;
const int N=405;
const int mod=998244353;
typedef long long ll;
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
void write(ll x){if(x>9) write(x/10);putchar(x%10+'0');}
ll n,q,m[15],sum[12][N][N],mi[12][N][N];
int seed;
inline ll fpow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
inline ll solve(ll a,ll b,ll c){ //这里要O(n)查询
ll res=0;
for(int i=1;i<=n;++i){
if(mi[i][a][b]<=c) ++res;
}
return res;
}
void Solve(){
cin>>n>>q;
for(int i=0;i<=n;++i){
for(int j=0;j<=400;++j){
for(int k=0;k<=400;++k){
sum[i][j][k]=mi[i][j][k]=inf;
}
}
}
for(int i=1;i<=n;++i){
cin>>m[i];
for(int j=1;j<=m[i];++j){
ll a,b,c;
cin>>a>>b>>c;
sum[i][a][b]=min(sum[i][a][b],c);
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=400;++j){
for(int k=1;k<=400;++k){
mi[i][j][k]=min(sum[i][j][k],min(mi[i][j-1][k],mi[i][j][k-1]));
}
}
}
cin>>seed;
#include <random>
mt19937 rng(seed);
uniform_int_distribution<> u(1,400);
int lastans=0;
ll ans=0;
for (int i=1;i<=q;i++){ //2e6
int IQ=(u(rng)^lastans)%400+1; // The IQ of the i-th friend
int EQ=(u(rng)^lastans)%400+1; // The EQ of the i-th friend
int AQ=(u(rng)^lastans)%400+1; // The AQ of the i-th friend
lastans=solve(IQ,EQ,AQ); // The answer to the i-th friend
// cout<<lastans<<" lst !!\n";
ans=(ans+lastans*fpow(seed,q-i)%mod)%mod;
}
cout<<ans<<"\n";
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
// cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;
return 0;
}
E - Jobs (Hard Version)
#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int N=405,mod=998244353;
typedef long long ll;
int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
inline ll fpow(ll a, ll b){
ll res=1;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int sum[405][405][405],a[405][405];
int n, q;
set<pair<int,int>> s[1000005]; //某个公司最小b,c值的集合
struct node{
int x,y,id;
};
vector<node>e[405];
inline void add(int x1, int y1, int x2, int y2){ //对a做差分
++a[x1][y1];
--a[x1][y2];
--a[x2][y1];
++a[x2][y2];
}
void insert(int i,int x,int y){ //将x和y插入i集合中
auto it=s[i].lower_bound({x,y});
int last=x;
auto tmp=it;
int y1 = tmp == s[i].begin() ? 401 : (--tmp)->second;
if (y1<=y) return; //存在更小的c则不需要插入
while(1){
if (it==s[i].end()) break;
add(last,y,it->first,y1);
if (it->second<y) break;
tmp = it++;
last = tmp->first;
y1 = tmp->second;
s[i].erase(tmp);
}
s[i].insert({x, y});
}
signed main() {
n=read();q=read();
for(int i=1,m;i<=n;i++){
s[i].insert({401,0});
m=read();
for(int j=1,a,b,c;j<=m;j++){
a=read();b=read();c=read();
e[a].push_back({b,c,i});
}
}
for(int i=1;i<=400;++i){ //枚举每一个a
for(auto it:e[i]){
insert(it.id,it.x,it.y); //将所有公司的b,c插入
}
for(int x=1;x<=400;++x) { //更新i的前缀和
for(int y=1;y<=400;++y){
sum[i][x][y]=sum[i][x-1][y]+sum[i][x][y-1]-sum[i][x-1][y-1]+a[x][y];
}
}
}
int seed;
seed=read();
mt19937 rng(seed);
uniform_int_distribution<> u(1, 400);
int lastans=0;
ll ans=0;
for (int i=1; i<=q; i++) {
int IQ=(u(rng)^lastans)%400+1; // The IQ of the i-th friend
int EQ=(u(rng)^lastans)%400+1; // The EQ of the i-th friend
int AQ=(u(rng)^lastans)%400+1; // The AQ of the i-th friend
lastans=sum[IQ][EQ][AQ];
ans=(lastans+ans*seed%mod)%mod;
}
write(ans);putchar('\n');
return 0;
}
F - Palindromic Tree
G - Wall Builder I
H - Wall Builder II
暴力枚举宽度,宽度一定时每一层尽量塞砖块进去肯定是最优的。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=105;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
struct node{
int x1,y1,x2,y2;
}tmp[N*N];
int n,cnt[N],has[N];
vector<node>vt,ans;
void Solve(){
cin>>n;
int sum=0,C=inf;
for(int i=1;i<=n;++i) cnt[i]=n-i+1,sum+=cnt[i]*i; //每个砖的数量
for(int p=n;p<=sum;++p){ //枚举宽
if(sum%p!=0||((sum/p)+p)>=C) continue;
int hang=0,tmp=sum,flag=0; //最开始有行数i
for(int i=1;i<=n;++i) has[i]=cnt[i];
vt.clear();
while(tmp){
int r=0;
for(int k=n;k>=1;--k){
while(r+k<=p&&has[k]){
vt.emplace_back((node){r,hang,r+k,hang+1});
--has[k];
r+=k;
tmp-=k;
}
}
if(r==p) ++hang;
else{
flag=1;
break;
}
}
if(flag) continue; //不能组成一个矩形
C=(sum/p+p);
swap(ans,vt);
}
cout<<2*C<<"\n";
for(auto to:ans){
cout<<to.x1<<" "<<to.y1<<" "<<to.x2<<" "<<to.y2<<"\n";
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;
return 0;
}
I - Three Body
J - Counting Fish Again
K - NIO’s Sword
最多7次我们就可以使1e6范围内的所有数都可达,并且每次变化的起点和终点都是固定的,枚举走x步从s出发可以到达的范围即可。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
int n,ans=0,pw[15];
inline int calc(int s,int t){
int res=0,L,R;
while(1){
++res;
L=s,R=s+pw[res];
if(L<=t&&t<R||L<=t+n&&t+n<R) break;
s=s*10%n;
}
return res;
}
void Solve(){
pw[0]=1;for(int i=1;i<=7;++i) pw[i]=pw[i-1]*10;
cin>>n;
if(n==1){
cout<<"0\n";
return;
}
for(int i=1;i<=n;++i){
ans+=calc((i-1)*10%n,i%n);
}
cout<<ans<<"\n";
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
int T=1;
// cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;
return 0;
}
L - Black Hole
首先,合法的只有4面体、6面体、8面体、12面体和20面体。然后手玩或者geogebra一下得知每种形状变化后的对应关系。 4 − > 4 , 6 − > 8 , 8 − > 6 , 12 − > 20 , 20 − > 12 4->4,6->8,8->6,12->20,20->12 4−>4,6−>8,8−>6,12−>20,20−>12。然后抄一手公式求出边长就ok了。
//#pragma GCC optimize("Ofast", "inline", "-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define int long long
#define double long double
using namespace std;
const int N=2e5+7;
const int mod=1e9+7;
//int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
double a,mp[25],g=(1+sqrtl(5.0))/2.0;
int n,k,nxt[25];
void Solve(){
cin>>n>>a>>k;
if(n!=4&&n!=6&&n!=8&&n!=12&&n!=20){
cout<<"impossible\n";
}else{
for(int i=1;i<=k;++i) a*=mp[n],n=nxt[n];
printf("possible %d %.15Lf\n",n,a);
}
}
signed main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
// freopen("in.cpp","r",stdin);
// freopen("out.cpp","w",stdout);
mp[4]=1.0/3;
mp[6]=sqrtl(2.0)/2;
mp[8]=sqrtl(2.0)/3;
mp[12]=2.0*g/sqrtl(3.0-g)*g/sqrtl(10.0+2.0*sqrtl(5));
mp[20]=(3.0+sqrtl(5.0))/(6.0*g);
nxt[4]=4;nxt[6]=8;nxt[8]=6;nxt[12]=20;nxt[20]=12;
int T=1;
cin>>T;
// clock_t start,finish;
// start=clock();
while(T--){
Solve();
}
// finish=clock();
// cerr<<((double)finish-start)/CLOCKS_PER_SEC<<endl;
return 0;
}
M - Monotone Chain
自己的板子套上了walkalone大佬的代码补的题……双指针太妙了。
#include<bits/stdc++.h>
#define Vector Point
//#define inf 0x7f7f7f7f
//#define int long long
//#define db long double
#define db long long
using namespace std;
typedef long long ll;
//const int N=1e5+7;
const db eps=1e-10,pi=acos(-1.0);
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
//inline int dcmp(db a){return a<-eps?-1:(a>eps?1:0);} //处理精度
//inline db Abs(db a){return a*dcmp(a);} //取绝对值
struct Point{
db x,y;
Point(){ SetZero(); }
Point(db _x,db _y){ Set(_x,_y); }
inline void Set(db _x,db _y){ x=_x,y=_y; }
inline void SetZero(){ x=y=0; }
inline Point operator +(const Point &v) const{ return Point(x+v.x,y+v.y); }
inline Point operator +=(const Point &v){ return *this=*this+v; }
inline Point operator -() const{ return Point(-x,-y); }
inline Point operator -(const Point &v) const{ return Point(x-v.x,y-v.y); }
inline Point operator -=(const Point &v){ return *this=*this-v; }
inline Point operator *(db f) const{ return Point(f*x,f*y); }
inline friend Point operator *(db f,const Point &v){ return v*f; }
inline Point operator *=(db f){ return *this=*this*f; }
inline Point operator /(db f) const{ return *this*(1.0/f); }
inline Point operator /=(db f){ return *this=*this/f; }
inline bool operator <(const Point &b){
auto up=[](const Point &a){
if(a.IsZero()) return -1;
return int(a.y>eps||(a.y>-eps&&a.x>-eps));
};
int qa=up(*this),qb=up(b);
if(qa!=qb) return qa>qb;
return Cross(*this,b)>eps;
}
inline bool IsZero() const{ return abs(x)<=eps&&abs(y)<=eps; }
inline bool operator ==(const Point &v) const{ return (*this-v).IsZero(); }
inline friend db Cross(const Point &p,const Point &q){ return p.x*q.y-p.y*q.x; }
inline friend db Dot(const Point &p,const Point &q){ return p.x*q.x+p.y*q.y; }
inline Point Rot90() const{ return Point(-y,x); }
inline Point Rot90CW() const{ return Point(y,-x); }
inline db SqrLen() const{ return x*x+y*y; }
inline db Length() const{ return sqrt(x*x+y*y); }
inline Point Normalized() const{
db len=Length();
if(len<=eps) return Point(0,0);
db invLen=1.0/len;
return Point(x*invLen,y*invLen);
}
inline Point Normalize(){ return *this=this->Normalized(); }
inline db Arg() const{ return atan2(y,x); }
inline friend istream &operator >>(istream &is,Point &v){ return is>>v.x>>v.y; }
inline friend ostream &operator <<(ostream &os,const Point &v){
os<<setiosflags(ios::fixed)<<setprecision(6);
os<<"("<<setw(9)<<v.x<<','<<setw(9)<<v.y<<")";
return os<<setprecision(6)<<resetiosflags(ios::fixed);
}
};
struct Line{
int u,v;
Point ori,dir;
Line(){ SetZero(); }
Line(const Point &_ori,const Point &_dir){ Set(_ori,_dir); }
inline void Set(const Point &_ori,const Point &_dir){
ori=_ori,dir=_dir.Normalized();
}
inline void SetdbwoPoints(const Point &p1,const Point &p2){ Set(p1,p2-p1); }
inline void SetZero(){ ori.SetZero(),dir.Set(1,0); }
inline bool OnLeft(const Point &p){
return Cross(dir,p-ori)>0;
}
inline db Arg() const{ return dir.Arg(); }
inline friend Point Intersect(const Line &lA,const Line &lB){
db k=Cross(lB.ori-lA.ori,lB.dir)/Cross(lA.dir,lB.dir);
return lA.ori+lA.dir*k;
}
};
bool argcmp(const Point &a,const Point &b){
const auto quad=[](const Point &a){
if(a.y<-eps) return 1;
if(a.y>eps) return 4;
if(a.x<-eps) return 5;
if(a.x>eps) return 3;
return 0;
};
int qa=quad(a),qb=quad(b);
if(qa!=qb) return qa<qb;
const auto t=Cross(a,b);
return t>eps;
}
signed main(){
int n=read();
vector<Point>pt(n);
for(int i=0;i<n;++i) scanf("%lld%lld",&pt[i].x,&pt[i].y);
vector<Point>que;
for(int i=1;i<n;++i){ //将向量加入队列
ll x=pt[i].x-pt[i-1].x,y=pt[i].y-pt[i-1].y;
if(x||y){
Point st=(Point){x,y};
que.emplace_back(st);
}
}
n=que.size();
if(!n){ //一个点的情况
printf("YES\n 0 0 1 0");
return 0;
}
sort(que.begin(),que.end(),argcmp); //极角排序
for(int i=0;i<n;++i) que.emplace_back(que[i]);
for(int l=0,r=0;l<n;++l){ //双指针,统计覆盖的射线数目
while(r<l+n&&(Cross(que[l],que[r]))>=0) ++r;
if(r==l+n){
printf("YES\n0 0 %lld %lld\n",-que[l].y,que[l].x);
return 0;
}
}
printf("NO");
}
N - Particle Arts
首先重构一下数组,把每一位上的1统计起来,然后尽量放,就得到了序列 x x x,即总和记为 s u m sum sum。
σ 2 = 1 n ( x i − μ ) 2 \sigma^2=\frac{1}{n}(x_i-\mu)^2 σ2=n1(xi−μ)2代入 μ \mu μ再拆开平方项,两边同除 1 n 2 \frac{1}{n^2} n21得: σ 2 n 3 = s u m i = 1 n ( x [ i ] ∗ n − s u m ) 2 \frac{\sigma^2}{n^3}=sum_{i=1}^n(x[i]*n-sum)^2 n3σ2=sumi=1n(x[i]∗n−sum)2,最后gcd约分一下结果,然后特判一下0就可以了。
#include <bits/stdc++.h>
#define int __int128
using namespace std;
int read(){ int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=f*-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
int n,sum,cnt,num,x,f[1000050],ans;
int gcd(int a,int b)
{
if (a%b==0) return b;
else return gcd(b,a%b);
}
signed main()
{
n=read();
for (int i=1;i<=n;++i)
{
x=read();
sum+=x;
cnt=0ll;
while (x)
{
f[cnt++]+=(x&1);
x>>=1;
}
}
if (sum==0) { printf("0/1\n"); return 0; }
for (int i=1;i<=n;++i)
{
num=0ll;
for (int j=0;j<=20;++j)
if (f[j]) {
f[j]--;
num|=(1<<j);
}
ans=ans+(num*n-sum)*(num*n-sum);
}
if (ans==0) { printf("0/1\n"); return 0;}
int fenmu=n*n*n;
int y=gcd(ans,fenmu);
write(ans/y);
putchar('/');
write(fenmu/y);
return 0;
}

908

被折叠的 条评论
为什么被折叠?



