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;
}
posted @ 2023-10-20 08:38  programmingysx  阅读(22)  评论(0编辑  收藏  举报