AT_abc327 会题解

发布时间 2023-11-07 19:23:57作者: NBest

2023.11.7 18:53

上一次打 ATCoder 还是在上次呢?上一次打外网网络比赛还是在暑假集训吧。

A

乱搞。

B

最多 \(15^{15}\),乱搞即可,记得开 long long 和中途退出。

C

...记得好像做过类似的题来着,同样乱搞。

D

类似于条件之间的叠加,直接建图跑个拓扑判环即可(寻思着要不学一下 2-SAT 和差分约束啥的,不管了先挖个坑)。

\(D_Code\)

int n,a[2][N],m,vis[N];
vector<int>f[N];
bool dfs(int x){
    for(int y:f[x]){
        if(vis[y]==vis[x])return 0;
        if(!vis[y]){
            vis[y]=-vis[x];
            if(!dfs(y))return 0;
        }
    }
    return 1;
}
bool work(){
    for(int i=1;i<=m;i++){
        if(a[0][i]==a[1][i])return 0;
        f[a[0][i]].push_back(a[1][i]);
        f[a[1][i]].push_back(a[0][i]);
    }
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            vis[i]=1;
            if(!dfs(i))return 0;
        }
    }
    return 1;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=m;i++)a[0][i]=read();
    for(int i=1;i<=m;i++)a[1][i]=read();
    puts(work()?"Yes":"No");
    return 0;
}

E

卡住了,一开始贪心打挂了,后面执着于二分甚至连正解打出来了都不自知,把二分去掉就过了。就是个简单 dp,从右往左枚举选了几个算 \(\sum_{i=1}^{k}(0.9)^{k-i}Q_i\),对于相同的个数这个最大就一定最大,然后就做完了,最后枚举个数即可,复杂度 \(O(n^2)\)。写完这题就剩下几分钟结束了,直接开摆。

代码稍微优化了一下,看着好看极了。

\(Code\)

const int N=5003;
int n,a[N];
typedef long double ld;
ld pp[N]={1},f[2][N],ans=-1e9;
int main(){
    n=read();
    for(int i=1;i<=n;i++)a[i]=read(),pp[i]=pp[i-1]*0.9;
    for(int i=n,o=1;i;--i,o^=1)
        for(int j=1;j<=n;j++)
            f[o][j]=max(f[o^1][j],f[o^1][j-1]+pp[j-1]*a[i]);
    for(int k=1;k<=n;k++)
        ans=max(ans,f[n&1][k]/(10.0-pp[k]*10)-1200.0/sqrtl(k));
    printf("%.8LF\n",ans);
}

F

二维变一维想到扫描线,而这里有限制 \(x,t\) 的范围求最大值,我们不妨按照套路静一动一,排序后双指针枚举 \(x\),然后把符合范围要求的加入贡献,而贡献的计算就是算每个苹果能对哪些时间范围早成贡献,可以用线段树区间加维护,最后求全局最大值即可,这题甚至不需要离散化,复杂度 \(O(n\log n)\)

\(Code\)

PII a[N+5];
int n,d,w,tr[(N<<2)+5],lazy[(N<<2)+5],ans;
inline void add(int root,int v){tr[root]+=v,lazy[root]+=v;}
void update(int root,int l,int r,int x,int y,int v){
    if(x<=l&&r<=y)return add(root,v),void();
    add(root<<1,lazy[root]),add(root<<1|1,lazy[root]),lazy[root]=0;
    int mid=l+r>>1;
    if(mid>=x)update(root<<1,l,mid,x,y,v);
    if(mid<y)update(root<<1|1,mid+1,r,x,y,v);
    tr[root]=max(tr[root<<1],tr[root<<1|1]);
}
int main(){
    n=read(),d=read(),w=read();
    for(int i=1;i<=n;i++)a[i].first=read(),a[i].second=read();
    sort(a+1,a+1+n);
    for(int i=1,l=0;i<=n;i++){
        while(l<n&&a[l+1].first-a[i].first<d)
            l++,update(1,1,N,max(a[l].second-w+1,1),a[l].second,1);
        ans=max(ans,tr[1]);
        update(1,1,N,max(a[i].second-w+1,1),a[i].second,-1);
    }
    cout<<ans;
}

G

红题不会。