本人 6年级 耗时5个月luoguP1335 [NOI2013] 小 Q 的修炼AC
接下来由我为大家讲解
我们不难发现,数据非常的小,体现在选择跳转操作次数极小,可以打 (2)O(2n) 的暴力 AC。
这个点其实有着和 C1,C2 同样的性质,即它可以分成一段一段的,每一个段都会让你做几个选择改变一些变量,而最后答案加上变量的绝对值后所有变量清零。发现每一个段内的选择跳转次数同样很小,那么我们只需要针对每一个段爆搜寻找最大值并输出即可。
= 2,意味着仅有一个变量需要讨论,我们发现,该变量在整个数据中增加的次数仅有一,再看就发现这实际上就是一个输出序列的背包,数据中可以分成均匀的段模拟一个物品,不难实现。:
我们只是片面的看 C4,但是 C5,C6 却又多出了两个问题,第一个是跳转不再均匀,如果不满足条件可能会跳到任意地方,这个可以通过更改背包实现方法做到,但此时又出现了一些无意义的条件跳转,它使得数据不均匀,可以通过把分段背包改成对每一个操作进行的背包解决,不过这真的很慢。
接下来送出AC代码 代码为C++98 运行
感谢大家的收看
#include
#include
const int V=14,N=35005,A=35008,M=1005;// test4,5,<6>:6005,5005;test7,9,<8,10>:17505,505;
long long a3[50]={// test3 answers in 40 bits each
105025473538,966002026284,29071798794,828015681698,345076144512,7609663648,75572971281,893434105988,55374250029,69357298497,
352188367880,606129394432,114391256076,280284430482,21342331152,71438241792,552864354484,277310738817,292830118913,356817845002,
171866350220,738738866178,124730794401,567011710064,276090593300,146336664705,105370633227,8766641162,554084534088,220354604,
275834439762,689661677592,384430491443,35505128705,362000505380,717277582337,551404199944,28525008900,42180411432,111962951362,
756249821316,104178523169,970685944448,826990151840,550066487844,56014938624,183102753072,498235172866,367371821952,111820754965};
int a4[37]={// test4 answers in 27 bits each
53023363,126569282,96699504,125433988,17903708,69782701,20011427,79325988,34426572,28519852,73662648,88093828,111679748,2720499,
8722643,3446989,98607969,271677,9013658,3140163,39583877,77874946,99252525,50794073,5960927,58906286,79851791,88096402,74645533,
115779693,19405473,127156765,89097393,106777648,37504704,102765283,13775654};
unsigned long long a5[13]={// test5 answers in 64 bits each
2472856109046735176u,14002470006381216419u,9262603746387061448u,6104175549895418148u,7607447720203324760u,
187054435080471040u,5353311602114594057u,164434300413151236u,2361575248052781509u,13060549033956755920u,
5208747512806155908u,10268288548647211096u,365918613798536540u};
long long a6[27]={// test6 answers in 62 bits each (last 2 bits)
666561470791453834,1729506503910555649,1820336247838048257,2596477065037643856,3100253491970001298,163286823920616015,
2328926311216709921,72175963486029064,590699291673794698,204705753251760660,3828359061153417744,1303335264944398336,
202697865605156866,2615963992162836498,329888760768694018,621699622038413633,2666220147825584499,3532141525318238720,
2380312005330277632,1747441495029332032,2327959566721058,72847716460568,2316697975426211916,40657756361169032,
1804290062196671040,1153076123540803754,1};
long long a7[12]={// test7 answers in 59 bits each
289371728581395457,310917708224022918,432673915156992129,92439373709716,60969088262112900,180427088468117266,
288850917766209560,348800277039612173,37300107343960064,466198364938662177,171246780233581188,6195843585607456};
long long a8[26]={// test8 answers in 60 bits each
436851556240202128,320952240972169344,217862320797254786,671053939362237516,181235804575166570,615104196660708658,
110410215534461280,937392306218190916,180250608760397316,919319539388330248,225397204725022848,74957196852923410,
432948406513698948,650784448821486624,29317520330667042,1010636069278025026,576497019087552538,759648838537643024,
580160480624060672,756740007198849,457293020212232262,960814983426876439,81491529437841712,27041382735906,
126823173202186320,289403177676179586};
unsigned a9[24]={// test9 answers in 32 bits each (last 3 bits)
1193329154,1590464,536907172,2489843731u,2776638656u,1149374741,2152764096u,628365956,291504464u,370689288,554979736,2156048405u,
2500526662u,2358710786u,2583830544u,302061122,3239837704u,3291750465u,2853479073u,3557598720u,1109418096,2476297,2148142594u,1};
unsigned long long a0[21]={// test0 answers in 64 bits each
10518157104275071364u,4667473803902504966u,7309395008707106436u,414353260389222929u,10396155124933787696u,5409401570930753833u,
9804901606886507040u,2398345886717036552u,2621121964663669060u,20409170001208612u,8359108107631337984u,2902622827133285410u,
6341376625002840532u,15043716074745184520u,146403419686438155u,2454467377358963270u,2955571372396644672u,4900343875164176387u,
2684446886765880320u,2450108453038178437u,615147073809121411u,};
struct F{int i,j,ch;F(){}F(int a,int b,int c){i=a,j=b,ch=c;}}la[A][M];
int n,v,vr[V],cr=1,ch,cc,ab[A],at[A],che[A],d[A][M],it;
struct cmd_game{//common:1 for +, -1 for - || cond: 6 || choiche: 8
char lne[55];int op,d,var1,var2,con1,con2,lne1,lne2,*fet1,*fet2;
int getnum(int &p){int x=0,sgn=1;if(lne[p]=='-')sgn=-1,p++;
while(lne[p]>='0'&&lne[p]<='9')x=x*10+lne[p]-'0',p++;return x*sgn;
}void getvar(int &p){int x,cx=(lne[p]=='c');p+=2;x=getnum(p);
if(!d){cx?con1=x:var1=x;fet1=cx?&con1:&vr[var1];d=1;}
else {cx?con2=x:var2=x;fet2=cx?&con2:&vr[var2];}
}void make(){int p=0;if(lne[0]=='s'){op=8;p+=2;lne1=getnum(p);p++;lne2=getnum(p);}
if(lne[0]=='i'){op=6;p+=2;getvar(p);p++;getvar(p);p++;lne1=getnum(p);p++;lne2=getnum(p);}
if(lne[0]=='v'||lne[0]=='c'){op=1;getvar(p);p++;if(lne[p]=='-')op=-1;p++;p++;getvar(p);}
}void r(int &le){int c=0;
if(op==1||op==-1){*fet1+=op*(*fet2);le++;}if(op==6){if(*fet1<*fet2)le=lne1;else le=lne2;}
if(op==8){if(it)c=1+at[cc++];else c=1+((ch>>(cc++))&1);if(c==1)le=lne1;else le=lne2;}
}
}cd[N];
void input(){scanf("%d%d\n",&n,&v);for(int i=1;i<=n;i++)gets(cd[i].lne),cd[i].make();}
void rb(){for(int i=1;i>=1;dig--;}}
void answer(){unsigned long long x=0;
if(n==11&&v==2)output(8,6);// example test
else if(n==183&&v==12)output(0,4);// test1
else if(n==350&&v==12)output(4393556,25);// test2
else if(n==34000&&v==12)for(int i=0;i<50;i++)output(a3[i],40);// test3
else if(n==6001&&v==2&&cd[n-1].op==1)for(int i=0;i<37;i++)output(a4[i],27);// test4
else if(n==6001&&v==2&&cd[n-1].op==6)for(int i=0;i<13;i++)output(a5[i],64);// test5
else if(n==12001&&v==2){for(int i=0;i<26;i++)output(a6[i],62);output(a6[26],2);}// test6
else if(n==17501&&v==12&&cd[n-1].op==-1)for(int i=0;i<12;i++)output(a7[i],59);// test7
else if(n==35001&&v==12&&cd[n-1].op==-1)for(int i=0;i<26;i++)output(a8[i],60);// test8
else if(n==17501&&v==12&&cd[n-1].op==6){for(int i=0;i<23;i++)output(a9[i],32);output(a9[23],3);}// test9
else if(n==35001&&v==12&&cd[n-1].op==6)for(int i=0;i<21;i++)output(a0[i],64);// test0
}
int testblock(){// for searching test 1,2,3
int mx,mt;/*for(int K=0;K<100;K++){*/mx=mt=0;for(ch=0;ch<(1<<10);ch++){rb();
cr=6656,cc=0;while(cr<=6825)cd[cr].r(cr);if(vr[1]>mx)mx=vr[1],mt=ch;}ch=mt;return mx;//}
}
int tb(int lne){// for searching block in test 7,8,9,10
if(che[lne])return che[lne];if(cd[lne].op!=8||cd[lne-1].op!=-1)printf("Wrong at %d\n",lne);
int mx=0,mt=0;for(ch=0;ch<(1<<10);ch++){rb();cr=lne,cc=0;
while(crmx)mx=vr[1],mt=ch;}ab[lne]=-1-mt;return che[lne]=mx;
}
void recur(int i,int j,int val){
if(i)recur(la[i][j].i,la[i][j].j,la[i][j].ch);int dt=10;
if(val>0)at[cc++]=val-1;else if(val<0){val=-1-val;while(dt)at[cc++]=val&1,val>>=1,dt--;}
}
void testmoney(){// for test 4,5,6,(7,8,9!,10!)
//for(int i=1;i<=n;i++)if(cd[i].op==8)che[i]=++cnt;//brutal force searching all
memset(d,0x80,sizeof(d));int m=cd[1].con2,inf=d[0][0],cnt=0,l1,l2;d[2][m]=0;
for(int i=2;i<=n;i++)for(int j=0;j<=m;j++)if(d[i][j]!=inf){
l1=cd[i].lne1,l2=cd[i].lne2;if(cd[i].op==8){
if(d[l1][j]=cd[i].con2&&d[l2][j]mx)mx=d[n+1][i],mt=i;cc=0;recur(n+1,mt,0);
//printf("Maximum score:%d at var[2]=%d\n",mx,mt);
}/*else if(cd[i].op==-1){l2=cd[i].con2;if(l2>j)l2=j;
if(d[i+1][j-l2]