C20220805T3 零和
作者:互联网
当构造出长度为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