20231019
20231019 NOIP#24总结
时间安排
7:40~8:10
看题,\(A,B,C\) 各会一点,\(D\) 没想法。
8:10~8:30
写 \(A\) 的暴力。
8:30~9:00
写 \(C\) 的暴力。
9:00~9:30
会 \(A\) 写了。
9:30~11:00
马上看出了 \(B\) 的做法,但是可能太久没写了写挂了,调了一个小时。
11:00~11:40
\(D\) 写半天看错题意,后来一下想出了两档的做法,可惜还剩 \(10\) 分钟。
总结反思
- 仔细读题,好好手模样例
- 加快比赛节奏
题解
A.数学
值域只有 \(1e6\),直接开桶统计个数。枚举答案,将所有答案倍数的个数都加起来,若 \(\geq k\) 则答案合法。复杂度是调和极数。
B.边带权并查集
边带权并查集板子。
C.状压
考虑将边权从大到小加入,设 \(f[s]\) 表示已经确定了 \(s\) 集合的边权情况下的最小值。新加入一条边时,由于是从大到小加入,产生的代价就是连接的两个联通块点权和的乘积在乘上边权,用并查集维护每个状态即可。
D.数据结构
这个题解不太会写,感觉要加好多图片,不如看原题解。
题解
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int s=0,k=1;
char c=getchar();
while(c>'9'||c<'0'){
if(c=='-') k=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
s=(s<<3)+(s<<1)+(c^48);
c=getchar();
}
return s*k;
}
const int N=4e5+10,V=1.5e6+10;
int n,m,w,h,cnt;
struct node{
int fl,l,r,id;
long double v;
}c[N<<3];
long double ans[N];
namespace FenwickTree{
long double s[5],c[5][V];
void clear(){
memset(c,0,sizeof(c));
memset(s,0,sizeof(s));
}
void add(int fl,int x,long double v){
s[fl]+=v; x+=h+2;
while(x<V){
c[fl][x]+=v;
x+=x&-x;
}
}
long double query(int fl,int x,bool vis){
long double ans=0;
x+=h+2;
while(x>0){
ans+=c[fl][x];
x-=x&-x;
}
if(vis) return s[fl]-ans;
return ans;
}
}
int main(){
freopen("dedescription.in","r",stdin);
freopen("dedescription.out","w",stdout);
n=read();m=read();w=read();h=read();
for(int i=1,x,y,l;i<=n;i++){
x=read();y=read();l=read();
c[++cnt]={0,x,y-l,0,1};
c[++cnt]={0,x,y+l,0,1};
c[++cnt]={0,x-l,y,0,-1};
c[++cnt]={0,x+l,y,0,-1};
}
for(int i=1,l,r,u,v;i<=m;i++){
l=read();r=read();u=read();v=read();
c[++cnt]={1,r,v,i,1};
c[++cnt]={1,l,u,i,1};
c[++cnt]={1,l,v,i,-1};
c[++cnt]={1,r,u,i,-1};
}
FenwickTree::clear();
sort(c+1,c+1+cnt,[](node x,node y){return x.r==y.r?x.fl<y.fl:x.r<y.r;});
for(int i=1;i<=cnt;i++){
if(!c[i].fl){
int dn=c[i].l-c[i].r;
FenwickTree::add(0,dn,c[i].v);
FenwickTree::add(1,dn,c[i].v*c[i].r);
FenwickTree::add(2,dn,c[i].v*c[i].r*c[i].r);
}
else{
int dn=c[i].l-c[i].r;
long double t=0;
t+=FenwickTree::query(2,dn,0);
t-=FenwickTree::query(1,dn,0)*c[i].r*2;
t+=FenwickTree::query(0,dn,0)*c[i].r*c[i].r;
ans[c[i].id]+=t*c[i].v;
}
}
FenwickTree::clear();
sort(c+1,c+1+cnt,[](node x,node y){return x.l==y.l?x.fl<y.fl:x.l<y.l;});
for(int i=1;i<=cnt;i++){
if(!c[i].fl){
int dn=c[i].l-c[i].r;
FenwickTree::add(0,dn,c[i].v);
FenwickTree::add(1,dn,c[i].v*c[i].r);
FenwickTree::add(2,dn,c[i].v*c[i].r*c[i].r);
FenwickTree::add(4,dn,c[i].v*dn*dn);
FenwickTree::add(3,dn,c[i].v*dn);
}
else{
int dn=c[i].l-c[i].r;
long double t=0;
t+=FenwickTree::query(2,dn,1);
t-=FenwickTree::query(1,dn,1)*c[i].r*2;
t+=FenwickTree::query(0,dn,1)*c[i].r*c[i].r;
t-=FenwickTree::query(0,dn,1)*dn*dn/2;
t+=FenwickTree::query(3,dn,1)*dn;
t-=FenwickTree::query(4,dn,1)/2;
ans[c[i].id]+=t*c[i].v;
}
}
FenwickTree::clear();
sort(c+1,c+1+cnt,[](node x,node y){return x.l==y.l?x.fl>y.fl:x.l>y.l;});
for(int i=1;i<=cnt;i++){
if(!c[i].fl){
int up=c[i].l+c[i].r;
FenwickTree::add(0,up,c[i].v);
FenwickTree::add(1,up,c[i].v*up);
FenwickTree::add(2,up,c[i].v*up*up);
}
else{
int up=c[i].l+c[i].r;
long double t=0;
t+=FenwickTree::query(2,up-1,0)/2;
t-=FenwickTree::query(1,up-1,0)*up;
t+=FenwickTree::query(0,up-1,0)*up*up/2;
ans[c[i].id]+=t*c[i].v;
}
}
for(int i=1;i<=m;i++) printf("%.1Lf\n",ans[i]);
return 0;
}