Codeforces Round 908 C

发布时间 2023-12-07 01:23:30作者: ycllz

111
发现要是所有的l r求和 L R 的差距>n 我们总可以找到一个x不在n个不同的aij里
然后我们知道L R 的差距不大于1e5
我们枚举这个最终的个数为now
我们钦定选满所有的非now的元素
看是否差一些元素达到now
当然维护过程中我们要注意l[i] r[i]的限制
但是我们枚举now之后再枚举每一个集合肯定是n^2的
我们考虑直接用一个map存这个now出现在了哪些集合里 我们拿出来搞就是了
这样为什么不会卡成n^2 因为now就1e5个 所以复杂度就是nlog的

void solve() {
    int n;cin>>n;
    vector<int>x(n+1),l(n+1),r(n+1),sum(n+1);
    map<int,int>mp[n+1];
    int mn=0,mx=0,sumx=0,SUM=0;
    vector<int>A;
    map<int,vector<int>>v;
    for(int i=1;i<=n;i++){
        cin>>x[i]>>l[i]>>r[i];
        sumx+=x[i];
        mn+=l[i];
        mx+=r[i];
        vector<int>a(x[i]+1),c(x[i]+1);
        for(int j=1;j<=x[i];j++){
            cin>>a[j];
            A.push_back(a[j]);
            v[a[j]].push_back(i);
        }
        for(int j=1;j<=x[i];j++){
            cin>>c[j];
            sum[i]+=c[j];
            mp[i][a[j]]=c[j];
        }
        SUM+=min(r[i],sum[i]);
    }
    int ans=1e18;
    if(mx-mn>sumx){
        cout<<0<<endl;
        return;
    }
    for(int now=mn;now<=mx;now++){
        int res=SUM,res1=0;
        for(auto i:v[now]){
            if(mp[i].count(now)){
                res-=min(r[i],sum[i]);
                res+=min(r[i],sum[i]-mp[i][now]);
                res1+=max(0ll,l[i]-sum[i]+mp[i][now]);
            }
        }
        ans=min(ans,max(0ll,now-res-res1)+res1);
    }
    cout<<ans<<endl;
}