最近好水啊感觉浑身无力仿佛已经退役。。对于自己暴力选手的本质已经有个清晰的认知了
敢写就能A系列
容易发现结果只和奇偶性有关。如果n和m奇偶性不同肯定不能赢,如果相同肯定改成不同。
那么就是如果能一发赢掉就Awin,不然就输lor
#include
#include
#include
int main(void) {
int T; scanf("%d",&T);
for (;T--;) {
int n,m; scanf("%d%d",&n,&m);
if (n==m) puts("Yes");
else puts("No");
}
return 0;
}
水题,我们发现所有数字的和值域是[-666300,666300]的,于是暴力dp计数就可以了
#include
#include
#include
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
const int MOD=100000007;
const int N=670*300;
int f[2][N*2+505],a[305];
void upd(int &x,int y) {
x=(x+y)%MOD;
}
int main(void) {
int n; scanf("%d",&n);
rep(i,1,n) scanf("%d",&a[i]);
int now=0;
f[0][0+N]=1;
rep(i,1,n) {
now^=1;
fill(f[now],0);
rep(j,-199800,199800) if (j!=666) {
if (-j!=666) upd(f[now][j+N],f[!now][-j+N]);
if (j-a[i]>=-199800&&j-a[i]<=199800&&j-a[i]!=666) upd(f[now][j+N],f[!now][j-a[i]+N]);
}
int ggg=0;
}
printf("%d\n", f[now][-666+N]);
return 0;
}
无聊题,根据攻♂受关系(雾,并查集维护最受的那个点就可以了。最优的m个就排序嘛
#include
#include
#include
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int N=200005;
int fa[N],c[N];
LL size[N];
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
int find(int x) {
return (!fa[x])?x:(fa[x]=find(fa[x]));
}
bool cmp(int x,int y) {
return size[x]>size[y];
}
int main(void) {
int n=read(),m=read();
rep(i,1,n) size[i]=read();
rep(i,1,n) {
int x=read();
int fi=find(i);
int fx=find(x);
if (fi!=fx) {
fa[fi]=fx;
size[fx]+=size[fi];
}
}
rep(i,1,n) if (find(i)==i) {
c[++c[0]]=i;
}
std:: sort(c+1,c+c[0]+1,cmp);
LL ans=0;
rep(i,1,c[0]) {
if (m) {
ans+=size[c[i]];
m--;
}
}
printf("%lld\n", ans);
return 0;
}
非常巧妙的思路
我们把给定序列的桶记作A[]
注意到异或满足 A ⊕ B = C ↔ A ⊕ C = B A\oplus B=C\leftrightarrow A\oplus C=B A⊕B=C↔A⊕C=B,我们二分一个答案然后把所有可能的异或结果找出来扔桶里,记作B[]
对A[]和B[]做异或卷积,记得到C[],那么若C中存在方案数恰好为n的位置说明这里是一个可行解
于是这样做是 O ( n log ( n ) log ( log ( n ) ) ) O(n\log(n)\log(\log(n))) O(nlog(n)log(log(n)))的。
#include
#include
#include
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const int MOD=998244353;
const int ny2=499122177;
const int N=2000005;
int a[N],b[N],c[N],lim;
char s[N];
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
void FWT(int *a,int n,int f) {
for (int i=1;i<n;i<<=1) {
for (int j=0;j<n;j+=(i<<1)) {
for (int k=0;k<i;++k) {
int u=a[j+k],v=a[j+k+i];
a[j+k]=(u+v>=MOD)?(u+v-MOD):(u+v);
a[j+k+i]=(u-v+MOD>=MOD)?(u-v):(u-v+MOD);
if (f==-1) {
a[j+k]=1LL*a[j+k]*ny2%MOD;
a[j+k+i]=1LL*a[j+k+i]*ny2%MOD;
}
}
}
}
}
bool check(int n,int mid) {
for (register int i=0;i<lim;++i) b[i]=(c[i]<=mid);
FWT(b,lim,1);
for (register int i=0;i<lim;++i) b[i]=1LL*b[i]*a[i]%MOD;
FWT(b,lim,-1);
for (register int i=0;i<lim;++i) if (b[i]==n) {
return true;
}
return false;
}
int main(void) {
freopen("data.in","r",stdin);
int n=read(),m=read(); lim=(1<<m);
for (int i=0;i<lim;++i) c[i]=c[i>>1]+(i&1);
rep(i,1,n) {
scanf("%s",s); int x=0;
rep(j,0,m-1) x+=((s[j]=='1')<<j);
a[x]++;
}
FWT(a,lim,1);
int l,r,ans=m;
for (l=0,r=m;l<=r;) {
int mid=(l+r)>>1;
if (check(n,mid)) r=mid-1,ans=mid;
else l=mid+1;
}
printf("%d\n", ans);
return 0;
}
高中知识系列
首先判掉相离的情况,显然就是0
然后判掉包含的情况,显然就是小球体积
画图观察我们要求的到底是什么,可以发现是两个共底面的球缺,直观地讲就是一刀切苹果切下来的部分(当然你说留下的部分好像也没毛病
图片来源见水印,球缺指的就是缺掉的那一部分
考虑怎么求这个体积。我们以球心为原点,平行于球缺底面任意一方向为x轴,垂直于球缺底面方向为y轴
记R为球的半径,h为球缺高,那么球缺的体积就是 ∫ R − h R ( π ⋅ x 2 ) d y \int_{R-h}^{R} \left(\pi\cdot x^2\right)dy ∫R−hR(π⋅x2)dy
我们的坐标实际上是取在球的某一个剖面的边界上
注意到 x 2 + y 2 = R 2 x^2+y^2=R^2 x2+y2=R2,因此 x 2 = R 2 − y 2 x^2=R^2-y^2 x2=R2−y2
原柿等价于 ∫ R − h R [ π ⋅ ( R 2 − y 2 ) ] d y \int_{R-h}^{R} \left[\pi\cdot\left(R^2-y^2\right)\right]dy ∫R−hR[π⋅(R2−y2)]dy
于是用我们的高中知识即可知道 V = π R h 2 − 1 3 π h 3 V=\pi Rh^2-\frac{1}{3}\pi h^3 V=πRh2−31πh3
然后它们的交就是两个球缺的体积了,至于h同样可以用余弦定理这个高中知识解决,这里就不细说了
当然还有别的做法,比如先算球冠面积然后比出(球缺+圆锥)的体积,减一减就可以了吧
#include
#include
#include
#include
const double pi=acos(-1);
const int MAX=100+10;
const int inf=1e9+7;
struct Point {
double x,y,z,r;
} w,s;
int n;
double dis(Point p,Point q) {
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y)+(p.z-q.z)*(p.z-q.z));
}
int main(void) {
scanf("%lf%lf%lf%lf",&w.x,&w.y,&w.z,&w.r);
scanf("%lf%lf%lf%lf",&s.x,&s.y,&s.z,&s.r);
double ans=(4.0/3)*pi*(w.r*w.r*w.r+s.r*s.r*s.r);
double d=dis(s,w);
if (d>=s.r+w.r) ans=ans;
else if (d+w.r<=s.r) ans-=4.0/3*pi*w.r*w.r*w.r;
else if (d+s.r<=w.r) ans-=4.0/3*pi*s.r*s.r*s.r;
else {
double co=(s.r*s.r+d*d-w.r*w.r)/(2.0*d*s.r);
double h=s.r*(1-co);
ans-=(1.0/3)*pi*(3.0*s.r-h)*h*h;
co=(w.r*w.r+d*d-s.r*s.r)/(2.0*d*w.r);
h=w.r*(1-co);
ans-=(1.0/3)*pi*(3.0*w.r-h)*h*h;
}
printf("%.10lf\n",ans);
return 0;
}
留坑待更