CF Sasha and Array(最长注释,长达50行)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<iostream> #include<cstring> #define num ch-'0' #define int long long using namespace std; typedef long long ll; const int N=100000+10; const int mod=1e9+7; void read(int &x){ char ch;x=0; while(!isdigit(ch=getchar())); for(x=num;isdigit(ch=getchar());x=x*10+num); } void red(ll &x){ char ch;x=0; while(!isdigit(ch=getchar())); for(x=num;isdigit(ch=getchar());x=x*10+num); } int n,m; ll a[N]; struct T{ ll a[3][3]; //T() {memset(a,0,sizeof a);laz[1][1]=laz[2][2]=1;} void clear(){ //memset(a,0,sizeof a); for(int i=0;i<3;i++) for(int j=0;j<3;j++) a[i][j]=0; } void init(){ a[1][1]=a[2][2]=1; } bool empty(){ if(a[1][1]!=1) return 0; if(a[1][2]!=0) return 0; if(a[2][1]!=0) return 0; if(a[2][2]!=1) return 0; return 1; } T operator + (T b){ T c;c.clear(); for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) c.a[i][j]=(c.a[i][j]+b.a[i][j]+a[i][j])%mod; return c; }/*void print(){ for(int i=1;i<=2;i++) { for(int j=1;j<=2;j++) cout<<a[i][j]<<" "; cout<<endl; } }*/ T operator * (T b){ T c;c.clear(); for(int i=1;i<=2;i++) for(int k=1;k<=2;k++) for(int j=1;j<=2;j++) c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mod; //c.print(); return c; } }t[4*N],laz[4*N],M,B; T qm(T a,ll y){ T ret,base; ret.clear(),ret.init(); while(y){ if(y&1) ret=ret*a; a=a*a; y>>=1; } return ret; } void pushup(int x){ t[x]=t[x<<1]+t[x<<1|1]; } void build(int x,int l,int r){ laz[x].clear();laz[x].init(); t[x].clear(); if(l==r){ t[x]=qm(M,a[l]-1); //cout<<l<<" : "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl; //laz[x].print(); return; } //laz[x].clear(),laz[x].init(); int mid=l+r>>1; build(x<<1,l,mid);build(x<<1|1,mid+1,r); pushup(x); // if(l==1&&r==3){ // cout<<" get "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl; // } } void pushdown(int x,int l,int r) { //if(laz[x].empty()) return; //if(laz[x].a[1][1]==1&&laz[x].a[2][2]==1&&laz[x].a[2][1]==0&&laz[x].a[1][2]==0) return; if(laz[x].empty()) return; int ls=(x<<1),rs=(x<<1|1); //cout<<" here "<<l<<" "<<r<<endl; //if(l==10&&r==14) laz[x].print(); //cout<<" before "<<endl; //t[ls].print(); puts("");t[rs].print(); // laz[x].print(); //cout<<" ans "<<endl; //(t[ls]*laz[x]).print(); t[ls]=t[ls]*laz[x]; //cout<<" cc "<<endl;cc.print(); //t[ls]=cc; //cout<<"ls:";t[ls].print(); //T dd=t[rs]*laz[x]; t[rs]=t[rs]*laz[x]; //t[ls].print(),puts(""),t[rs].print(); //cout<<"laz "<<laz[rs].pr laz[ls]=laz[ls]*laz[x]; laz[rs]=laz[rs]*laz[x]; //cout<<" after "<<endl; // puts("");t[rs].print(); // t[x].laz[1][1]=t[x].laz[2][2]=1; laz[x].clear();laz[x].init(); //t[x].laz=0; } void update(int x,int l,int r,int L,int R,T c) { //cout<<" ffff "<<l<<" "<<r<<" "<<endl; if(L<=l&&r<=R){ // cout<<" l and r "<<l<<" "<<r<<endl; // cout<<" laz1 "<<lz<<" laz2 "<<t[x].laz<<endl; t[x]=t[x]*c; // cout<<" lazy "<<t[x].laz<<endl; //t[x]=t[x]*c; laz[x]=laz[x]*c; //if(l==1&&r==5) laz[x].print(); //if(L==8&&R==15) c.print(); //if(l==10&&r==14) laz[x].print(); // if(l==1&&r==3){ // cout<<" get222 "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl; //} return; } pushdown(x,l,r); int mid=l+r>>1; if(L<=mid) update(x<<1,l,mid,L,R,c); if(mid<R) update(x<<1|1,mid+1,r,L,R,c); pushup(x); //if(l==1&&r==3){ // cout<<" get222 "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl; //} } T query(int x,int l,int r,int L,int R) { //if(L==1&&R==3) cout<<"finding "<<l<<" "<<r<<endl; //cout<<" finding "<<l<<" "<<r<<endl; //if(l==1&&r==5) laz[x].print(); if(L<=l&&r<=R){ // if(l==4&&r==5) t[x].print(); return t[x]; } //cout<<" dfdfdfdfd "<<l<<" "<<r<<endl; pushdown(x,l,r); //cout<<" fdfdfdf "<<l<<" "<<r<<endl; T ret;ret.clear(); //ret.print(); int mid=l+r>>1; //query(x<<1,l,mid,L,R).print(); if(L<=mid) ret=ret+query(x<<1,l,mid,L,R); if(mid<R) ret=ret+query(x<<1|1,mid+1,r,L,R); //cout<<" after "<<l<<" "<<r<<" : "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl; return ret; } ll work(int l,int r) { T ret;ret.clear(); ret=B*query(1,1,n,l,r); return ret.a[1][1]; } signed main() { B.clear(),M.clear(); B.a[1][1]=1;//B.a[1][2]=1; M.a[1][1]=M.a[1][2]=M.a[2][1]=1; //scanf("%I64d%I64d",&n,&m); read(n);read(m); for(int i=1;i<=n;i++) red(a[i]); //scanf("%I64d",&a[i]); build(1,1,n); int op,l,r; ll z; while(m--){ // scanf("%I64d",&op); //cout<<"mmmm "<<m<<endl; read(op); if(op==1){ //scanf("%I64d%I64d%I64d",&l,&r,&z); read(l);read(r);red(z); //cout<<" before "<<z<<" "<<endl; T k;k=qm(M,z); //cout<<" after "<<z<<endl; //cout<<k.a[1][1]<<" "<<k.a[1][2]<<" "<<k.a[2][1]<<" "<<k.a[2][2]<<endl; update(1,1,n,l,r,k); } else{ //scanf("%I64d%I64d",&l,&r); read(l);read(r); printf("%I64d\n",work(l,r)); } } return 0; }
尤其pushdown满篇注释,其实就错了两点:
1.数组越界了...后果:c++不会告诉你RE,只是不知道在哪里就卡崩了。
现象:莫名的错误;直接赋值出错,间接赋值没错;cout在前可以正确输出,操作一下别的什么东西,cout在后就错了。
死坑死坑死坑的。
2.注释太多,漏了laz之间的下放。。。。
以后,注释没用还是删掉一些为好。
洛谷P4208 [JSOI2008]最小生成树计数(182行 2.5h)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<bits/stdc++.h> using namespace std; const int mod=31011; const int N=100+10; const double eps=1e-8; typedef long long ll; int n,m; int fa[N],ff[N]; struct node{ int x,y; int val; }bian[1000+20]; bool cmp(node a,node b){ return a.val<b.val; } int fin(int x){ if(fa[x]==x) return x; return fa[x]=fin(fa[x]); } int inf(int x){ if(ff[x]==x) return x; return ff[x]=inf(ff[x]); } void mer(int x,int y){ int k1=fin(x); int k2=fin(y); if(k1!=k2){ fa[k1]=k2; } } bool cmp2(int a,int b){ return fin(bian[a].x)<fin(bian[b].x); } struct tr{ double f[N][N]; int cnt; void init(){ memset(f,0,sizeof f);cnt=0; } tr operator -(const tr &b){ tr c;c.init();c.cnt=cnt; for(int i=1;i<=cnt;i++) for(int j=1;j<=cnt;j++) c.f[i][j]=f[i][j]-b.f[i][j]; return c; } void op(){ cout<<endl; for(int i=1;i<=cnt;i++){ cout<<i<<" | "; for(int j=1;j<=cnt;j++) cout<<f[i][j]<<" "; cout<<endl; } } }; ll gauss(tr S){ int s=S.cnt; double a[N][N]; memcpy(a,S.f,sizeof S.f); int sign=0; for(int i=1;i<=s;i++){ int id=i; for(int j=i+1;j<=s;j++){ if(fabs(a[j][i])>fabs(a[id][i])) id=j; } if(id!=i){ for(int j=1;j<=s;j++) swap(a[i][j],a[id][j]); } for(int j=i+1;j<=s;j++){ double ch=a[j][i]/a[i][i]; for(int k=1;k<=s;k++){ a[j][k]=a[j][k]-a[i][k]*ch; } } } double ret=1.0; for(int i=1;i<=s;i++) ret*=a[i][i]; ll ans=(ll)(ret+eps+eps); ans=abs(ans); return ans%mod; } int mem[N],mems; int edge[N],tot; int du[N]; int li(int x){ int k=lower_bound(mem+1,mem+mems+1,x)-mem; return k; } ll ans=1; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++){ scanf("%d%d%d",&bian[i].x,&bian[i].y,&bian[i].val); } sort(bian+1,bian+m+1,cmp); for(int i=1;i<=m;i++){ //mst int x=bian[i].x,y=bian[i].y; if(fin(x)!=fin(y)){ mer(x,y); } } //for(int i=1;i<=n;i++) fin(i),cout<<fa[i]<<" "; //cout<<endl; for(int i=1;i<=n;i++) int k=fin(i); int faa=fa[1]; for(int i=2;i<=n;i++) if(fa[i]!=faa){ printf("0");return 0; } for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++){ //cout<<"--------------------------"<<i<<"---------------------------"<<endl; memset(edge,0,sizeof edge);tot=0; int nc=bian[i].val; int st=i,ed; while(bian[i].val==nc){ int k1=fin(bian[i].x); int k2=fin(bian[i].y); if(k1!=k2){ //cout<<i<<" : "<<bian[i].x<<" "<<bian[i].y<<" : "<<k1<<" "<<k2<<endl; edge[++tot]=i; } i++; } i--; memcpy(ff,fa,sizeof fa); for(int j=1;j<=tot;j++){ mer(bian[edge[j]].x,bian[edge[j]].y); } ///for(int j=1;j<=tot;j++) cout<<edge[j]<<" "; //cout<<endl; sort(edge+1,edge+tot+1,cmp2); for(int j=1;j<=tot;j++){ //cout<<"***********"<<j<<"**********"<<endl; int now=fin(bian[edge[j]].x); memset(mem,0,sizeof mem);mems=0; int st=j,ed; while(fin(bian[edge[j]].x)==now){ int k1=inf(bian[edge[j]].x); int k2=inf(bian[edge[j]].y); mem[++mems]=k1; mem[++mems]=k2; j++; } j--; ed=j; sort(mem+1,mem+mems+1); mems=unique(mem+1,mem+mems+1)-mem-1; /*cout<<"members "<<mems<<endl; for(int j=1;j<=mems;j++) cout<<mem[j]<<" "; cout<<endl;*/ tr D,B;D.init();B.init(); D.cnt=B.cnt=mems; for(int j=st;j<=ed;j++){ //cout<<bian[edge[j]].x<<" && "<<bian[edge[j]].y<<endl; int x=li(inf(bian[edge[j]].x)); int y=li(inf(bian[edge[j]].y)); //cout<<" after li "<<x<<" && "<<y<<endl; D.f[x][x]+=1.0,D.f[y][y]+=1.0; B.f[x][y]+=1.0,B.f[y][x]+=1.0; } //D.op(); //B.op(); tr A=D-B; A.cnt--; ans=(ans*gauss(A))%mod; } } printf("%lld",ans);return 0; }
错误点在于:
1.存的edge[i]才是编号,用的时候,for(j 1~tot) bian[edge[j].x 而不是bian[j].x
2.矩阵树,基尔霍夫矩阵要去掉一行一列
3.对于相同的边,
找出能加入的
再找出最终是同一个联通块里的。再在每个联通块里跑矩阵树。否则跑不出生成树。
而不是选择出了能加入的边,就直接矩阵树。
[国家集训队]middle(181行 3h跨零点)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<bits/stdc++.h> using namespace std; const int N=20000+10; int n,m; int a[N],num[N],mem; int rt[N]; int x1,x2,x3,x4; int li(int x){ return lower_bound(num+1,num+mem+1,x)-num; } struct node{ int sum,lmx,rmx; int lson,rson; bool ncl,ncr; #define s(x) t[x].sum #define ls(x) t[x].lson #define rs(x) t[x].rson #define lm(x) t[x].lmx #define rm(x) t[x].rmx #define cl(x) t[x].ncl #define cr(x) t[x].ncr }t[N*40]; int tot; vector<int>pos[N]; void pushup(int x){ s(x)=s(ls(x))+s(rs(x)); lm(x)=max(lm(ls(x)),s(ls(x))+lm(rs(x))); rm(x)=max(rm(rs(x)),s(rs(x))+rm(ls(x))); } int build(int l,int r){ int id=++tot; if(l==r){ if(li(a[l])<=1) s(id)=lm(id)=rm(id)=-1; else s(id)=lm(id)=rm(id)=1; return id; } int mid=l+r>>1;cl(id)=1;cr(id)=1; ls(id)=build(l,mid);rs(id)=build(mid+1,r); pushup(id); return id; } int upda(int x,int y,int l,int r,int to,int c,bool nc){ //cout<<x<<" "<<y<<" : "<<l<<" and "<<r<<" : "<<to<<endl; if(!nc) { x=++tot; } if(l==r){ s(x)=lm(x)=rm(x)=c; return x; } int mid=(l+r)>>1; if(to<=mid){ if(!cr(x)) rs(x)=rs(y); if(!cl(x)){ cl(x)=1;ls(x)=upda(x,ls(y),l,mid,to,c,0); } else{ ls(x)=upda(ls(x),ls(y),l,mid,to,c,1); } } else{ if(!cl(x)) ls(x)=ls(y); if(!cr(x)){ cr(x)=1;rs(x)=upda(x,rs(y),mid+1,r,to,c,0); } else{ rs(x)=upda(rs(x),rs(y),mid+1,r,to,c,1); } } pushup(x); return x; } int qs(int x,int l,int r,int L,int R){ if(L<=l&&r<=R){ return s(x); } int mid=l+r>>1;int ret=0; if(L<=mid) ret+=qs(ls(x),l,mid,L,R); if(mid<R) ret+=qs(rs(x),mid+1,r,L,R); return ret; } node ql(int x,int l,int r,int L,int R){ if(L<=l&&r<=R){ return t[x]; } int mid=l+r>>1; if(L<=mid&&mid<R){ node ret; node le=ql(ls(x),l,mid,L,R); node ri=ql(rs(x),mid+1,r,L,R); ret.sum=le.sum+ri.sum; ret.lmx=max(le.lmx,le.sum+ri.lmx); return ret; } else if(L<=mid){ return ql(ls(x),l,mid,L,R); } else { return ql(rs(x),mid+1,r,L,R); } } node qr(int x,int l,int r,int L,int R){ //cout<<l<<" "<<r<<" goal "<<L<<" "<<R<<endl; if(L<=l&&r<=R){ return t[x]; } int mid=l+r>>1; if(L<=mid&&mid<R){ //cout<<" double "<<endl; node ret; node le=qr(ls(x),l,mid,L,R); node ri=qr(rs(x),mid+1,r,L,R); ret.sum=le.sum+ri.sum; ret.rmx=max(ri.rmx,ri.sum+le.rmx); //cout<<"le "<<le.rmx<<" ri "<<ri.rmx<<" "<<ri.sum<<endl; //cout<<"ret "<<ret.sum<<" "<<ret.rmx<<endl; return ret; } else if(L<=mid){ return qr(ls(x),l,mid,L,R); } else { return qr(rs(x),mid+1,r,L,R); } } bool che(int val){ int sz=0; if(x2+1<=x3-1) sz=qs(rt[val],1,n,x2+1,x3-1); int sr=ql(rt[val],1,n,x3,x4).lmx; int sl=qr(rt[val],1,n,x1,x2).rmx; // cout<<"in binary "<<val<<endl; //cout<<sl<<" "<<sz<<" "<<sr<<endl; return (sl+sz+sr)>=0; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),num[++mem]=a[i]; sort(num+1,num+mem+1); mem=unique(num+1,num+mem+1)-num-1; for(int i=1;i<=n;i++){ pos[li(a[i])].push_back(i); } rt[1]=build(1,n); for(int i=2;i<=mem;i++){ //cout<<"building "<<i<<"--------------------------------"<<endl; for(int j=0;j<pos[i-1].size();j++){ int go=pos[i-1][j]; //cout<<" update "<<go<<endl; rt[i]=upda(rt[i],rt[i-1],1,n,go,-1,rt[i]>0); } } //cout<<"root "<<endl; //for(int i=1;i<=mem;i++) cout<<rt[i]<<' ';cout<<endl; scanf("%d",&m); int las=0; int ch[6]; while(m--){ scanf("%d%d%d%d",&x1,&x2,&x3,&x4); ch[1]=(x1+las)%n; ch[2]=(x2+las)%n; ch[3]=(x3+las)%n; ch[4]=(x4+las)%n; sort(ch+1,ch+4+1); x1=ch[1]+1,x2=ch[2]+1,x3=ch[3]+1,x4=ch[4]+1; int l=1,r=mem; int ans=0; while(l<=r){ int mid=l+r>>1; if(che(mid)) ans=mid,l=mid+1; else r=mid-1; } las=num[ans]; printf("%d\n",las); } return 0; }
其实题目不是很难想明白就是难写。
错误点在于:
1.审题不清楚。这个题中位数的定义是:奇数中间一个,偶数中间靠后的那个。二分的>=0 和 >0 的区别
2.手抖手抖手抖手抖打错了!!!!pushup把rm(ls)打成rs(ls) -------------------直接出锅
(对拍过夜才找出来....)
[ZJOI2013]K大数查询(最后128行 5h跨零点)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<bits/stdc++.h> #define int long long using namespace std; typedef long long ll; const int N=50000+10; int n,m; struct node{ int l,r;ll c;int id;int op;ll ans; }q[N]; struct tr{ int sum,ad; }t[N*4]; int dp; int tc; vector<int>p[35]; int delepool[35]; void dele(int s){ delepool[++dp]=s; } int nc(){ int r=dp?delepool[dp--]:++tc; p[r].clear(); return r; } int ans[N]; int tot; void pushdown(int x,int l,int r){ int mid=l+r>>1; t[x<<1].sum+=t[x].ad*(mid-l+1); t[x<<1|1].sum+=t[x].ad*(r-mid); t[x<<1].ad+=t[x].ad; t[x<<1|1].ad+=t[x].ad; t[x].ad=0; } void add(int x,int l,int r,int L,int R,int c){ if(L<=l&&r<=R){ t[x].sum+=c*(r-l+1); t[x].ad+=c; return; } pushdown(x,l,r); int mid=l+r>>1; if(L<=mid) add(x<<1,l,mid,L,R,c); if(mid<R) add(x<<1|1,mid+1,r,L,R,c); t[x].sum=t[x<<1].sum+t[x<<1|1].sum; } int query(int x,int l,int r,int L,int R){ if(L<=l&&r<=R){ return t[x].sum; } pushdown(x,l,r); int mid=l+r>>1; int ret=0; if(L<=mid) ret+=query(x<<1,l,mid,L,R); if(mid<R) ret+=query(x<<1|1,mid+1,r,L,R); return ret; } void div(int id,ll l,ll r){ if(l==r){ for(int i=0;i<p[id].size();i++){ if(q[p[id][i]].op==2) q[p[id][i]].ans=l; } return; } ll mid=(ll)floor(((double)1.0*l+(double)1.0*r)/((double)2)); int le=nc(),ri=nc(); bool fl=false,fr=false; //le.clear();ri.clear(); for(int i=0;i<p[id].size();i++){ //cout<<" qu "<<p[id][i]<<" "<<q[p[id][i]].op<<endl; if(q[p[id][i]].op==1){ if(q[p[id][i]].c<=mid) p[le].push_back(p[id][i]); else { p[ri].push_back(p[id][i]); add(1,1,n,q[p[id][i]].l,q[p[id][i]].r,1); } } else{ int sum=query(1,1,n,q[p[id][i]].l,q[p[id][i]].r); //cout<<sum<<endl; if(sum>=q[p[id][i]].c){ fr=true; p[ri].push_back(p[id][i]); } else { fl=true; q[p[id][i]].c-=sum; p[le].push_back(p[id][i]); } } } for(int i=0;i<p[id].size();i++){ if(q[p[id][i]].op==1){ if(q[p[id][i]].c>mid) { add(1,1,n,q[p[id][i]].l,q[p[id][i]].r,-1); } } } //cout<<p[le].size()<<" and "<<fl<<" || "<<p[ri].size()<<" and "<<fr<<endl; if(p[le].size()&&fl)div(le,l,mid); dele(le); if(p[ri].size()&&fr)div(ri,mid+1,r); dele(ri); } signed main() { scanf("%d%d",&n,&m); int st=nc(); for(int i=1;i<=m;i++){ scanf("%d%d%d%lld",&q[i].op,&q[i].l,&q[i].r,&q[i].c); q[i].id=i; p[st].push_back(i); } //cout<<inf<<" "<<-inf<<endl; div(st,-n,n); for(int i=1;i<=m;i++){ if(q[i].op==2){ printf("%lld\n",q[i].ans); } } return 0; }
错误点:
1.vector开太多MLE,TLE
2.集合中没有询问,可以剪枝。
3.vector垃圾回收(l==r)dele多删了一次。
4.蜜汁#define int long long才可以!?!?!?!??!!(tmd坑了3h)
[SCOI2014]方伯伯的商场之旅(2days 3遍程序)
采用gzz的做法
错误程序1:状态:f[i][a-b][0/1] 起初没有枚举x填多少,直接复制跳过了。
直接复制显然是错的。首先,[1]->[0],[0]->[0]就有两种情况。其次,填不同的x,可能都会到达[0]状态。
错误程序2:怎么处理1呢?加一维记录一个[0/1/2]代表x这一位填的数和a[p]的相对大小。相当于保证x填的范围。
虽然可以转移过来,但是最后统计答案会出锅。因为,处理完位置p,统计答案的时候,枚举x,
假设x>a[p],就会取f[1][a-b][0/1][2]这个位置,会把不是填x这个数,但是也满足>a[p]的x的贡献算进去的。
例如:
三进制下:
上限是6:2 0
5 : 1 2(会在位置2合并)
4 : 1 1(会在位置1合并)
当枚举p=2时,1,2都满足比a[p]=0大,
当枚举x=2时,会加上f[last][a-b=1][1/0],但是,最后一位填1也会贡献到这里。
然后,本来代价是1,就变成了1+1=2
正确程序:
外层枚举一个pos,再枚举一个x,钦定p这一位填x。最后统计就一点没有问题了。
Code:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=70; const int M=22; const int fix=201; const int up=402; ll f[N][405][2]; ll g[N][405][2]; ll L,R; int m; ll ansl,ansr; int a[N],cnt; ll wrk(){ ll ret=0; for(int p=1;p<=cnt;p++){ //cout<<"---------------------------------- "<<p<<endl; for(int x=0;x<m;x++){ memset(f,0,sizeof f); memset(g,0,sizeof g); g[cnt+1][fix][1]=1; for(int i=cnt;i>=