码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 588

时间:2019-10-03 12:39:29      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:next   span   复杂   链表   证明   tin   include   修改   max   

A

\(n^2\) 删点+暴力更新+bfs。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long D;
typedef pair<D,D> P;
const int maxn=7003;
int n,tot[maxn];
P a[maxn];
bool del[maxn];
bitset<maxn> b[maxn];
queue<int> q;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i].second);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i].first);
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++){
        D suma=0;
        for(int j=1;j<=n;j++){
            if(i==j)continue;
            if((a[i].second&a[j].second)==a[i].second)suma+=a[i].first,b[i].set(j),tot[i]++;
        }
        if(!suma)q.push(i);
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        if(del[u])continue;
        del[u]=1;
        for(int i=1;i<=n;i++){
            if(!del[i]&&b[i][u]){
                b[i].reset(u);
                if(!--tot[i])q.push(i);
            }
        }
    }
    D ans=0;
    int cnt=0;
    for(int i=1;i<=n;i++)if(!del[i])ans+=a[i].first,cnt++;
    printf("%lld\n",cnt>=2?ans:0);
    return 0;
}

B

一个性质:从根到某个节点的gcd的数量不会超过log个。
因此从上往下更新答案,搞个map启发式合并即可。

C

链表维护一个节点的入边和出边,修改时暴力维护。可以证明复杂度最坏为 \(O(n\sqrt{n})\) (完全图)。 \(O(n\sqrt{n} \log n)\) 无法通过此题。

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=100003;
struct edge{int to,next;}e[maxn<<1];
int head[maxn],cnte;
void add(int u,int v){e[++cnte].to=v,e[cnte].next=head[u],head[u]=cnte;}
int n,m,in[maxn],out[maxn],hi[maxn],ho[maxn],pr[maxn<<1],nx[maxn<<1];
long long ans;
void add(int h[],int u,int i){
    nx[i]=h[u];
    if(h[u])pr[h[u]]=i;
    h[u]=i;
}
void del(int h[],int u,int i){
    if(i==h[u])h[u]=nx[h[u]];
    if(nx[i])pr[nx[i]]=pr[i];
    if(pr[i])nx[pr[i]]=nx[i];
    pr[i]=nx[i]=0;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    for(int u=1;u<=n;u++){
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(u>v)out[u]++,add(ho,u,i);
            else in[u]++,add(hi,u,i);
        }
    }
    for(int u=1;u<=n;u++){
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(u>v)ans+=out[v];
        }
    }
    printf("%lld\n",ans);
    int Q;
    scanf("%d",&Q);
    while(Q--){
        int u;
        scanf("%d",&u);
        ans-=1ll*in[u]*out[u];
        for(int i=hi[u],j;i;i=j){
            j=nx[i];
            int v=e[i].to;
            ans-=1ll*in[v]*out[v];
            del(hi,u,i);
            add(ho,u,i);
            in[u]--,out[u]++;
            i&1?i++:i--;
            del(ho,v,i);
            add(hi,v,i);
            out[v]--,in[v]++;
            ans+=1ll*in[v]*out[v];
        }
        ans+=1ll*in[u]*out[u];
        printf("%lld\n",ans);
    }
    return 0;
}

Codeforces 588

标签:next   span   复杂   链表   证明   tin   include   修改   max   

原文地址:https://www.cnblogs.com/BlogOfchc1234567890/p/11619485.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!