ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C20220805T3 零和

2022-08-31 13:05:06  阅读:174  来源: 互联网

标签:std vis C20220805T3 int push c11 define


当构造出长度为22的随机 \([1,5]\) 的集合后,出现合法方案的概率很大,所以可以先随便构造一种方案,然后再通过背包求出其他取值中可以满足的方案数(即先构造22个极小的整数,去找到其他负数,并将这几个负数以01背包的方式求出对应的方案数),最后离线 \(t\) 组询问,若有解就继续,若无解就重新构造,最后一个点正好跑到1000ms(时限2000ms),时间充裕。

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mp std::make_pair
#define pii std::pair<int,int>
#define chkmin(_A,_B) (_A=std::min(_A,_B))
#define chkmax(_A,_B) (_A=std::max(_A,_B))
//--------------------FastInOut--------------------//
class IO{
    public:
        inline char read(){
            static const int IN_LEN =1<<18|1;
            static char buf[IN_LEN],*s,*t;
            return (s==t)&&(t=(s=buf)+fread(buf, 1, IN_LEN, stdin)),(s==t)?-1:*s++;
        }
        template<typename _Tp>inline IO &operator >>(_Tp &x){
            static char c11, boo;
            for (c11=read(),boo=0;!isdigit(c11);c11=read()) {
                if (c11==-1)
                    return *this;
                boo|=(c11=='-');
            }
            for(x=0;isdigit(c11);c11=read())
                x=x*10+(c11^'0');
            if(boo)
                x=-x;
            return *this;
        }
        inline void push(const char &c) {
            putchar(c);
        }
        template<typename _Tp>inline IO &operator <<( _Tp x){
            if (x<0)
                x=-x,push('-');
            static _Tp sta[35];
            _Tp top=0;
            do{
                sta[top++]=x%10,x/=10;
            }while(x);
            while(top)
                push(sta[--top]+'0');
            return *this;
        }
        inline IO &operator <<(char lastChar){
            push(lastChar);
            return *this; 
        }
}FIO;

int rd[30];
std::vector<int> v;
int dp[205];
int head[1000005],to[40000005],nxt[40000005],id[40000005],ecnt,sum;
int vis[1000005],pre[1000005],lst[1000005];
void add(int u,int v,int w) {
    nxt[++ecnt]=head[u];
    to[ecnt]=v;
    id[ecnt]=w;
    head[u]=ecnt;
}
void print(int x,std::vector<int> &ans) {
    if (!x)
        return;
    ans.push_back(-pre[x]);
    print(lst[x], ans);
}
int main(){
    freopen("zero.in","r",stdin);
    freopen("zero.out","w",stdout);
    for(int i=1;i<=22;++i){
        rd[i]=rand()%5+1;
        sum+=rd[i];
        v.push_back(rd[i]);
    }
    dp[0]=1;
    for(int i=1;i<=22;++i){
        for(int j=sum;j>=rd[i];--j){
            dp[j]+=dp[j-rd[i]];
        }
    }
    for(int i=0;i<=1000000;i++){
        for (int j=std::max(1,sum-40);j<=sum;j++){
            if (i+dp[j]<=1000000){
                add(i,i+dp[j],j);
            }
        }
    }
    std::queue<int> q;
    q.push(0);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        vis[x]=1;
        for (int i=head[x];i;i=nxt[i]) {
            if (!vis[to[i]]){
                vis[to[i]]=1;
                pre[to[i]]=id[i];
                lst[to[i]]=x;
                q.push(to[i]);
            }
        }
    }
    int T;
    FIO>>T;
    while(T--){
        int x;
        FIO>>x;
        while(1){
            std::vector<int> ans=v;
            print(x-1,ans);
            if(ans.size()<=30){
                FIO<<ans.size()<<'\n';
                for (int i=0;i<(int)ans.size();++i)
                    FIO<<ans[i]<<' ';
                FIO<<'\n';
                break;
            }
            sum=0;
            memset(dp,0,sizeof(dp));
            memset(head,0,sizeof(head));
            memset(vis,0,sizeof(vis));
            v.clear();
            ecnt=0;
            for(int i=1;i<=22;++i){
                rd[i]=rand()%5+1;
                sum+=rd[i];
                v.push_back(rd[i]);
            }
            dp[0]=1;
            for(int i=1;i<=22;++i){
                for(int j=sum;j>=rd[i];--j){
                    dp[j]+=dp[j-rd[i]];
                }
            }
            for(int i=0;i<=1000000;i++){
                for (int j=std::max(1,sum-40);j<=sum;j++){
                    if (i+dp[j]<=1000000){
                        add(i,i+dp[j],j);
                    }
                }
            }
            std::queue<int> q;
            q.push(0);
            while(!q.empty()){
                int x=q.front();
                q.pop();
                vis[x]=1;
                for (int i=head[x];i;i=nxt[i]) {
                    if (!vis[to[i]]){
                        vis[to[i]]=1;
                        pre[to[i]]=id[i];
                        lst[to[i]]=x;
                        q.push(to[i]);
                    }
                }
            }
        }
    }
    return 0;
}

标签:std,vis,C20220805T3,int,push,c11,define
来源: https://www.cnblogs.com/zhouzizhe/p/16642688.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有