耗时最长代码合集
CF Sasha and Array(最长注释,长达50行)

#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)

#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跨零点)

#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跨零点)

#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:

#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>=1;i--){ //cout<<" i "<<" ---> "<<i<<endl; for(int j=0;j<=up;j++){ if(i==p){ if(x<a[i]){ if(g[i+1][j][0]) g[i][j][0]+=g[i+1][j][0],f[i][j][0]+=f[i+1][j][0]; if(g[i+1][j][1]) g[i][j][0]+=g[i+1][j][1],f[i][j][0]+=f[i+1][j][1]; } else if(x==a[i]){ g[i][j][1]+=g[i+1][j][1],f[i][j][1]+=f[i+1][j][1]; g[i][j][0]+=g[i+1][j][0],f[i][j][0]+=f[i+1][j][0]; } else{ g[i][j][0]+=g[i+1][j][0],f[i][j][0]+=f[i+1][j][0]; } continue; } for(int k=0;k<m;k++){ if(i>p){//before if(j+k>up) continue; if(k<a[i]){ g[i][j+k][0]+=g[i+1][j][0],f[i][j+k][0]+=f[i+1][j][0]+(i-p)*k*g[i+1][j][0]; g[i][j+k][0]+=g[i+1][j][1],f[i][j+k][0]+=f[i+1][j][1]+(i-p)*k*g[i+1][j][1]; } else if(k==a[i]){ g[i][j+k][0]+=g[i+1][j][0],f[i][j+k][0]+=f[i+1][j][0]+(i-p)*k*g[i+1][j][0]; g[i][j+k][1]+=g[i+1][j][1],f[i][j+k][1]+=f[i+1][j][1]+(i-p)*k*g[i+1][j][1]; } else{ g[i][j+k][0]+=g[i+1][j][0],f[i][j+k][0]+=f[i+1][j][0]+(i-p)*k*g[i+1][j][0]; } } else{//after //if(p==1)//cout<<" oh shit owierhffhr "<<endl; if(j-k<0) continue; if(k<a[i]){ f[i][j-k][0]+=f[i+1][j][0]+g[i+1][j][0]*(p-i)*k,g[i][j-k][0]+=g[i+1][j][0]; f[i][j-k][0]+=f[i+1][j][1]+g[i+1][j][1]*(p-i)*k,g[i][j-k][0]+=g[i+1][j][1]; } else if(k==a[i]){ f[i][j-k][0]+=f[i+1][j][0]+g[i+1][j][0]*(p-i)*k,g[i][j-k][0]+=g[i+1][j][0]; f[i][j-k][1]+=f[i+1][j][1]+g[i+1][j][1]*(p-i)*k,g[i][j-k][1]+=g[i+1][j][1]; } else{ f[i][j-k][0]+=f[i+1][j][0]+g[i+1][j][0]*(p-i)*k,g[i][j-k][0]+=g[i+1][j][0]; } } //if(i!=p){ /*if(j-fix>=0&&j-fix<=3){ cout<<j<<" and "<<k<<endl; cout<<" f "<<f[i][j+k][0]<<" "<<f[i][j+k][1]<<endl; cout<<" g "<<g[i][j+k][0]<<" "<<g[i][j+k][1]<<endl; }} else{ if(j-fix>=0&&j-fix<=3){ //cout<<j<<" and "<<k<<endl; //cout<<" f : q1 "<<f[i][j][0]<<" "<<f[i][j][1]<<" q2 "<<f[i][j][0][1]<<" "<<f[i][j][1][1]<<" q3 "<<f[i][j][0][2]<<" "<<f[i][j][1][2]<<endl; //cout<<" g : q1 "<<g[i][j][0]<<" "<<g[i][j][1<<" q2 "<<g[i][j][0][1]<<" "<<g[i][j][1][1]<<" q3 "<<g[i][j][0][2]<<" "<<g[i][j][1][2]<<endl; } }*/ } } } //cout<<" ins "<<x<<" ******************* "<<endl; for(int j=0;j<=up;j++){ //if(j-fix>=0&&j-fix<=3) // cout<<" jj "<<j<<endl; if((fix-x<=j)&&(j<x+fix)){ ret+=f[1][j][0]+f[1][j][1]; } //if(j-fix>=0&&j-fix<=3) // cout<<" ret "<<ret<<endl; } } //cout<<ret<<endl; } return ret; } int main(){ scanf("%lld%lld",&L,&R); scanf("%d",&m); L--; cnt=0; while(L){ a[++cnt]=L%m; L/=m; } if(cnt==0){ ansl=0; } else{ ansl=wrk(); } cnt=0; while(R){ a[++cnt]=R%m; R/=m; } //cout<<" R "<<cnt<<endl; //for(int i=cnt;i>=1;i--)cout<<a[i]<<" ";cout<<endl; ansr=wrk(); //cout<<ansr<<" "<<ansl<<endl; printf("%lld",ansr-ansl); }
[CQOI2016]手机号码
比较麻烦的数位dp,其实就花了大概50min
目前最长代码331行。。。。。记录一下而已。

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=13; ll l,r; ll f[N][2][10][10][2][2][2]; int num[N],cnt; bool is=false; ll wrk(){ memset(f,0,sizeof f); for(int i=0;i<=num[cnt]*10+num[cnt-1];i++){ int y=i%10,x=i/10; if(y==num[cnt-1]&&x==num[cnt]){ f[cnt-1][1][x][y][0][(x==4)||(y==4)][(x==8)||(y==8)]++; } else{ f[cnt-1][0][x][y][0][(x==4)||(y==4)][(x==8)||(y==8)]++; } } for(int i=cnt-2;i>=1;i--){ for(int j=0;j<=9;j++){ for(int k=0;k<=9;k++){ for(int p=0;p<=9;p++){ if(p<num[i]){ if(p==4){ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]; f[i][0][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]+f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]+f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][1][0]+=f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0]+f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]+ f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]+f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]+f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]+ f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0]+f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0]; } } else if(p==8){ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]; f[i][0][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]+f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]+f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][0][1]+=f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1]+f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]+ f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]+f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]+f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]+ f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1]+f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0]; } } else{ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]; f[i][0][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]; f[i][0][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]; f[i][0][k][p][0][1][0]+=f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]; f[i][0][k][p][0][0][1]+=f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][0][0]+=f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][0][0]+=f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+ f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]; f[i][0][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]+ f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]+ f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][0][0]+=f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]+ f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0]; } } } else if(p==num[i]){ if(p==4){ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][0][1]; f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][1][0]+=f[i+1][0][j][k][0][1][0]+f[i+1][0][j][k][0][0][0]; f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][1][j][k][1][0][1]; f[i][1][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][1][j][k][0][0][1]; f[i][1][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][1][j][k][1][0][0]; f[i][1][k][p][0][1][0]+=f[i+1][1][j][k][0][1][0]+f[i+1][1][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][0][1]+ f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][0][1]; f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][1][j][k][1][0][1]+ f[i+1][1][j][k][0][1][1]+f[i+1][1][j][k][0][0][1]; f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+f[i+1][0][j][k][1][0][0]+ f[i+1][0][j][k][0][1][0]+f[i+1][0][j][k][0][0][0]; f[i][1][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][1][j][k][1][0][0]+ f[i+1][1][j][k][0][1][0]+f[i+1][1][j][k][0][0][0]; } } else if(p==8){ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][1][0]; f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][0][1]+=f[i+1][0][j][k][0][0][1]+f[i+1][0][j][k][0][0][0]; f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][1][j][k][1][1][0]; f[i][1][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][1][j][k][0][1][0]; f[i][1][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][1][j][k][1][0][0]; f[i][1][k][p][0][0][1]+=f[i+1][1][j][k][0][0][1]+f[i+1][1][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][1][0]+ f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][1][0]; f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][1][j][k][1][1][0]+ f[i+1][1][j][k][0][1][1]+f[i+1][1][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+f[i+1][0][j][k][1][0][0]+ f[i+1][0][j][k][0][0][1]+f[i+1][0][j][k][0][0][0]; f[i][1][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][1][j][k][1][0][0]+ f[i+1][1][j][k][0][0][1]+f[i+1][1][j][k][0][0][0]; } } else{ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]; f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]; f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]; f[i][0][k][p][0][1][0]+=f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]; f[i][0][k][p][0][0][1]+=f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][0][0]+=f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][0][0]+=f[i+1][0][j][k][0][0][0]; f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]; f[i][1][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]; f[i][1][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]; f[i][1][k][p][0][1][0]+=f[i+1][1][j][k][0][1][0]; f[i][1][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]; f[i][1][k][p][0][0][1]+=f[i+1][1][j][k][0][0][1]; f[i][1][k][p][1][0][0]+=f[i+1][1][j][k][1][0][0]; f[i][1][k][p][0][0][0]+=f[i+1][1][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+ f[i+1][0][j][k][0][1][1]; f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+ f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+ f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][0][0]+=f[i+1][0][j][k][1][0][0]+ f[i+1][0][j][k][0][0][0]; f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+ f[i+1][1][j][k][0][1][1]; f[i][1][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+ f[i+1][1][j][k][0][1][0]; f[i][1][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+ f[i+1][1][j][k][0][0][1]; f[i][1][k][p][1][0][0]+=f[i+1][1][j][k][1][0][0]+ f[i+1][1][j][k][0][0][0]; } } } else{// p>num[i] if(p==4){ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][0][1]; f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][1][0]+=f[i+1][0][j][k][0][1][0]+f[i+1][0][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][0][1]+ f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+f[i+1][0][j][k][1][0][0]+ f[i+1][0][j][k][0][1][0]+f[i+1][0][j][k][0][0][0]; } } else if(p==8){ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][1][0]; f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][0][1]+=f[i+1][0][j][k][0][0][1]+f[i+1][0][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][1][0]+ f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+f[i+1][0][j][k][1][0][0]+ f[i+1][0][j][k][0][0][1]+f[i+1][0][j][k][0][0][0]; } } else{ if(k!=p||p!=j||j!=k){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]; f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]; f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]; f[i][0][k][p][0][1][0]+=f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]; f[i][0][k][p][0][0][1]+=f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][0][0]+=f[i+1][0][j][k][1][0][0]; f[i][0][k][p][0][0][0]+=f[i+1][0][j][k][0][0][0]; } else if (k==p&&p==j){ f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+ f[i+1][0][j][k][0][1][1]; f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+ f[i+1][0][j][k][0][1][0]; f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+ f[i+1][0][j][k][0][0][1]; f[i][0][k][p][1][0][0]+=f[i+1][0][j][k][1][0][0]+ f[i+1][0][j][k][0][0][0]; } } } } } } } ll ret=0; for(int j=0;j<=9;j++) for(int k=0;k<=9;k++){ ret+=f[1][0][j][k][1][1][0]+f[1][1][j][k][1][1][0]+f[1][0][j][k][1][0][1]+f[1][1][j][k][1][0][1]+f[1][0][j][k][1][0][0]+f[1][1][j][k][1][0][0]; } return ret; } int main() { scanf("%lld%lld",&l,&r); if(l!=1e10) l--; else is=true; while(l){ num[++cnt]=l%10;l/=10; } ll ans1=wrk(); cnt=0; while(r){ num[++cnt]=r%10;r/=10; } ll ans2=wrk(); printf("%lld",ans2-ans1+is); return 0; }
[NOI2005]维护数列(真·目前最长7h)
平衡树观止码农题。3h打码,4h调试。。。。
(其实对于基础的题目,不太清楚打标记什么的,也可以直接看题解。)

#include<bits/stdc++.h> #define rs t[x].ch[1] #define ls t[x].ch[0] #define numb ch-'0' #define ri register int #define il inline using namespace std; typedef long long ll; const int N=500000+5; const ll inf=(1LL*1<<61); char ch; il void rdint(int &x){ x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } il void rdll(ll &x){ x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } struct node{ int ch[2],fa; ll rm,lm,sum,ans; int rev; ll chan; ll val; int sz; void init(int f,ll v){ fa=f,val=v;rm=v;lm=v,ans=v,sum=v; rev=0,chan=inf; sz=1; } }t[N]; il ll Max(ll a,ll b){ return a>b?a:b; } int dc,dp[N],pc; int n,m,rt; ll st[N]; il int nc(){ int r=dc?dp[dc--]:++pc; memset(t+r,0,sizeof (node));return r; } il void pushup(int x){ t[x].sum=t[t[x].ch[0]].sum+t[t[x].ch[1]].sum+t[x].val; t[x].rm=Max(t[t[x].ch[1]].rm,Max(t[t[x].ch[1]].sum+t[x].val,t[t[x].ch[1]].sum+t[x].val+t[t[x].ch[0]].rm)); t[x].lm=Max(t[t[x].ch[0]].lm,Max(t[t[x].ch[0]].sum+t[x].val,t[t[x].ch[0]].sum+t[x].val+t[t[x].ch[1]].lm)); t[x].ans=Max(t[x].lm,t[x].rm); t[x].ans=Max(t[x].ans,Max(t[t[x].ch[0]].rm+t[x].val+t[t[x].ch[1]].lm,Max(t[t[x].ch[0]].rm+t[x].val,t[x].val+t[t[x].ch[1]].lm))); t[x].ans=Max(t[x].ans,Max(t[t[x].ch[0]].ans,t[t[x].ch[1]].ans)); t[x].ans=Max(t[x].ans,t[x].val);//bug 2 t[x].sz=t[t[x].ch[0]].sz+t[t[x].ch[1]].sz+1; } il void pushdown(int x){ if(t[x].chan!=inf){ if(ls){ t[ls].chan=t[x].chan; t[ls].val=t[x].chan; t[ls].sum=t[ls].val*t[ls].sz; t[ls].rm=t[ls].lm=t[ls].ans=t[ls].val>0?t[ls].sum:t[ls].val; } if(rs){ t[rs].chan=t[x].chan; t[rs].val=t[x].chan; t[rs].sum=t[rs].val*t[rs].sz; t[rs].rm=t[rs].lm=t[rs].ans=t[rs].val>0?t[rs].sum:t[rs].val; } t[x].chan=inf; } if(t[x].rev){ if(ls&&t[ls].val!=-inf){ t[ls].rev^=1; swap(t[ls].lm,t[ls].rm);//bug1 } if(rs&&t[rs].val!=-inf){ t[rs].rev^=1; swap(t[rs].lm,t[rs].rm);//bug1 } swap(ls,rs); t[x].rev=0; } } il void rotate(int x){ int y=t[x].fa,d=t[y].ch[1]==x; t[t[y].ch[d]=t[x].ch[!d]].fa=y; t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x; t[t[x].ch[!d]=y].fa=x; pushup(y); } il void splay1(int x,int f){ while(t[x].fa!=f){ int y=t[x].fa,z=t[y].fa; if(z!=f){ rotate((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x); } rotate(x); } pushup(x); if(f==0) rt=x; } il int kth(int k){ int x=rt; while(1){ pushdown(x); int d=k-t[t[x].ch[0]].sz; if(d<=0) x=t[x].ch[0]; else if(d==1) return x; else{ k=d-1; x=t[x].ch[1]; } } } int newrt; il void splay2(int x,int f){ while(t[x].fa!=f){ int y=t[x].fa,z=t[y].fa; if(z!=f){ rotate((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x); } rotate(x); } pushup(x); if(f==0) newrt=x; } il void build(ll v){ if(!newrt){ newrt=nc(); t[newrt].init(0,v); return; } int x=newrt; while(1){ if(!t[x].ch[1]){ t[x].ch[1]=nc(); t[t[x].ch[1]].init(x,v); x=t[x].ch[1]; break; } x=t[x].ch[1]; } splay2(x,0); } il int pre(int l,int r,int f){ if(l>r){ return 0; } int mid=(l+r)>>1; int x=nc(); t[x].init(f,st[mid]); t[x].ch[0]=pre(l,mid-1,x); t[x].ch[1]=pre(mid+1,r,x); pushup(x); return x; } il void ins(int pos,int tot){ newrt=0; for(ri i=1;i<=tot;i++){ rdll(st[i]); } newrt=pre(1,tot,0); int x=kth(pos+1); int y=kth(pos+2); splay1(x,0); splay1(y,x); t[y].ch[0]=newrt; t[newrt].fa=y; pushup(y); pushup(x); } il void del(int x){ if(t[x].ch[0]) del(t[x].ch[0]); dp[++dc]=x; if(t[x].ch[1]) del(t[x].ch[1]); } il void remove(int pos,int tot){ int l=kth(pos); int r=kth(pos+tot+1); splay1(l,0); splay1(r,l); del(t[r].ch[0]); t[r].ch[0]=0; pushup(r); pushup(l); } il void upda(int pos,int tot,ll c){ int l=kth(pos); int r=kth(pos+tot+1); splay1(l,0); splay1(r,l); int x=t[r].ch[0]; t[x].chan=c; t[x].val=c; t[x].sum=t[x].val*t[x].sz; t[x].rm=t[x].lm=t[x].ans=t[x].val>0?t[x].sum:t[x].val; pushup(r); pushup(l); } il void reverse(int pos,int tot){ int l=kth(pos); int r=kth(pos+tot+1); splay1(l,0); splay1(r,l); int x=t[r].ch[0]; t[x].rev^=1; swap(t[x].lm,t[x].rm); pushup(r); pushup(l); } il ll qs(int pos,int tot){ int l=kth(pos); int r=kth(pos+tot+1); splay1(l,0); splay1(r,l); int x=t[r].ch[0]; int ret=t[x].sum; pushdown(x);//bug 3 splay1(x,0); return ret; } int main() { t[0].lm=t[0].rm=t[0].ans=-inf;//warning warning warning !!! t[0].sz=0;t[0].sum=0; scanf("%d%d",&n,&m); st[1]=-inf; for(int i=2;i<=n+1;i++){ rdll(st[i]); } st[n+2]=-inf; rt=pre(1,n+2,0); char lp[20]; int pos,tot; ll c; int cnt=0; for(ri i=1;i<=m;i++){ ch=getchar(); while(ch>'Z'||ch<'A')ch=getchar(); for(cnt=0;(ch=='-')||(ch<='Z'&&ch>='A');ch=getchar())lp[++cnt]=ch; if(lp[1]=='I'){ rdint(pos),rdint(tot); if(tot==0) continue; ins(pos,tot); } else if(lp[1]=='D'){ rdint(pos),rdint(tot); if(tot==0) continue; remove(pos,tot); } else if(lp[1]=='M'&&lp[3]=='K'){ rdint(pos),rdint(tot);rdll(c); if(tot==0) continue; upda(pos,tot,c); } else if(lp[1]=='M'&&lp[3]=='X'){ printf("%lld\n",t[rt].ans); } else if(lp[1]=='G'){ rdint(pos),rdint(tot); if(tot==0) printf("0\n"); else printf("%lld\n",qs(pos,tot)); } else if(lp[1]=='R'){ rdint(pos),rdint(tot); if(tot==0) continue; reverse(pos,tot); } } return 0; }
相逢是问候(4h)
漂亮的数学+数据结构+预处理综合题。

#include<bits/stdc++.h> #define numb (ch^'0') #define mid ((l+r)>>1) using namespace std; typedef long long ll; const int N=50000+5; ll n,m,p,c; void rd(ll &x){ char ch;x=0; while(!isdigit(ch=getchar())); for(x=numb;isdigit(ch=getchar());x=(x<<1)+(x<<3)+numb); } ll a[N]; int b[N]; int up; int phi[N]; ll ci[N]; int ouler(ll x){ int ret=x; for(int i=2;i*i<=x;i++){ //cout<<i<<" "<<x<<endl; if(x%i==0){ ret=ret/i*(i-1); while(x%i==0) x/=i; } } if(x>1) ret=ret/x*(x-1); return ret; } ll num[N][35]; ll qm(ll x,ll y,ll mod){ ll ret=1%mod; while(y){ if(y&1) (ret*=x)%=mod; (x*=x)%=mod; y>>=1; } return ret; } ll mi1[10005][35]; ll mi2[10005][35]; ll tim(int id,int dep,int lim){ if(dep==lim){ return a[id]<phi[dep]?a[id]:a[id]%phi[dep]+phi[dep]; } ll tmp=tim(id,dep+1,lim); ll ret=0; if(c==1){ ret=1; if(ret>=phi[dep]) ret=ret%phi[dep]+phi[dep]; }else if(c==0){ ret=1; if(ret>=phi[dep]) ret=ret%phi[dep]+phi[dep]; }else{ if(tmp>50) ret=(mi2[tmp/10000][dep]*mi1[tmp%10000][dep]%phi[dep])+phi[dep]; else if(ci[tmp]<0||ci[tmp]>=phi[dep]) ret=(mi2[tmp/10000][dep]*mi1[tmp%10000][dep]%phi[dep])+phi[dep]; else ret=(mi2[tmp/10000][dep]*mi1[tmp%10000][dep]%phi[dep]); } return ret; } struct node{ ll mx,sum; }t[N<<2]; void pushup(int x){ t[x].sum=(t[x<<1].sum+t[x<<1|1].sum)%p; t[x].mx=max(t[x<<1].mx,t[x<<1|1].mx); } void build(int x,int l,int r){ if(l==r){ t[x].sum=a[l]; t[x].mx=up;return; } build(x<<1,l,mid);build(x<<1|1,mid+1,r); pushup(x); } void chan(int x,int l,int r,int L,int R){ if(L<=l&&r<=R){ if(l==r) { t[x].mx=max(t[x].mx-1,(ll)0); t[x].sum=num[l][up-t[x].mx]; return; } else{ if(t[x<<1].mx>0) chan(x<<1,l,mid,L,R); if(t[x<<1|1].mx>0) chan(x<<1|1,mid+1,r,L,R); pushup(x); return; } } else{ if(L<=mid) chan(x<<1,l,mid,L,R); if(mid<R) chan(x<<1|1,mid+1,r,L,R); pushup(x); return; } } ll query(int x,int l,int r,int L,int R){ if(L<=l&&r<=R){ return t[x].sum; } ll ret=0; if(L<=mid) (ret+=query(x<<1,l,mid,L,R))%=p; if(mid<R) (ret+=query(x<<1|1,mid+1,r,L,R))%=p; return ret; } int main(){ //freopen("1.in","r",stdin); //freopen("mine.out","w",stdout); rd(n);rd(m);rd(p);rd(c); ci[0]=1; for(int i=1;i<=50;i++){ ci[i]=ci[i-1]*c; if(ci[i]>2e9) ci[i]=-1; if(ci[i]<0) ci[i]=-1; } int tmp=p; phi[0]=p; while(tmp!=1){ up++; //if(up<15)cout<<up<<" "<<tmp<<endl; phi[up]=ouler(tmp); tmp=phi[up]; } up++;phi[up]=tmp; for(int j=0;j<=up;j++){ //cout<<j<<endl; mi1[0][j]=1%phi[j]; ll t=qm(c,10000,phi[j]); mi2[0][j]=1%phi[j]; for(int i=1;i<=10000;i++){ //cout<<i<<endl; mi1[i][j]=qm(c,i,phi[j]); mi2[i][j]=qm(t,i,phi[j]); } } //cout<<" up "<<up<<endl; for(int i=1;i<=n;i++) rd(a[i]); for(int i=1;i<=n;i++) { //cout<<" ii "<<i<<" ---------------"<<a[i]<<endl; //rd(a[i]); num[i][0]=a[i]; for(int j=1;j<=up;j++){ num[i][j]=tim(i,0,j)%p; //cout<<j<<" : "<<num[i][j]<<endl; } } //cout<<" num "<<num[8][0]<<" "<<num[8][1]<<" "<<num[8][2]<<" "<<num[8][3]<<endl; build(1,1,n); ll op,l,r; while(m--){ rd(op);rd(l);rd(r); if(op){ printf("%lld\n",query(1,1,n,l,r)); } else{ chan(1,1,n,l,r); } } return 0; }
列队(Splay)(2.5h)
平衡树蒟蒻,敲了半天。
其实思路很简单,就是把许多个人合并成一个区间。必要的时候再拆开。(是不是和这个题的动态开点线段树有异曲同工之妙?)
出错点:
1.pushup把哨兵sz变成了1:pushup要特判x!=0(比较保险)
2.fa和son的边一定要成对一起添加!!t[t[y].ch[0]=t[x].ch[0]].fa=y 压行的话不容易漏。
3.对于一列的情况,可能删除之后整个树空了。但是如果直接找的话,因为哨兵0有奇奇怪怪的左右儿子和father,所以,一路上会把0的sz变成1,并且访问到奇奇怪怪的点23333
那就特判如果没有根的话,那就直接建立即可。

#include<bits/stdc++.h> #define reg register int #define il inline using namespace std; typedef long long ll; const int N=300000+5; struct node{ int ch[2]; int sz; int L,R; int fa; ll val; }t[N*15]; int tot; void rd(int &x){ char ch;x=0; while(!isdigit(ch=getchar())); for(x=ch^'0';isdigit(ch=getchar());x=x*10+(ch^'0')); } int rt[N]; int now; int n,m,q; void pushup(int x){ if(x) t[x].sz=t[t[x].ch[0]].sz+t[t[x].ch[1]].sz+t[x].R-t[x].L+1; } void rotate(int x){ int y=t[x].fa,d=(t[y].ch[1]==x); t[t[y].ch[d]=t[x].ch[!d]].fa=y; t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x; t[t[x].ch[!d]=y].fa=x; pushup(y); } void splay(int x,int f){ while(t[x].fa!=f){ int y=t[x].fa,z=t[y].fa; if(z!=f){ rotate((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x); } rotate(x); } pushup(x); if(f==0) rt[now]=x; } ll get(int pos){ if(now==n+1){ return (ll)pos*m; } return (ll)(now-1)*m+pos; } void ins(int x,ll c){ if(x==0){ ++tot; t[tot].fa=0; t[tot].val=c; t[tot].L=t[tot].R=0; pushup(tot); rt[now]=tot; } else{ while(t[x].ch[1]) t[x].sz++,x=t[x].ch[1]; ++tot; t[x].ch[1]=tot; t[tot].fa=x; t[tot].L=t[tot].R=0;t[tot].val=c; t[tot].sz=1; pushup(x); // cout<<x<<": "<<" sz "<<t[x].sz<<" "<<t[x].fa<<" "<<t[t[x].fa].ch[0]<<endl; splay(tot,0); // cout<<t[rt[now]].sz<<" "<<endl; int tmp=rt[now]; // while(t[tmp].ch[0]) tmp=t[tmp].ch[0],cout<<"233 "<<tmp<<endl; } } ll query(int x,int k){//and dele // cout<<"--------------------------------- query "<<x<<" "<<k<<endl; int d=k-t[t[x].ch[0]].sz; if(d<=0) return query(t[x].ch[0],k); else if(t[x].R-t[x].L+1<d) return query(t[x].ch[1],d-(t[x].R-t[x].L+1)); else{//find position // cout<<" find "<<x<<endl; ll ret=0; if(t[x].R>t[x].L){ if(d>1){ ++tot; t[tot].L=t[x].L;t[tot].R=t[x].L+d-2; t[t[tot].ch[0]=t[x].ch[0]].fa=tot; t[t[x].ch[0]=tot].fa=x; pushup(tot); } if(d<t[x].R-t[x].L+1){ ++tot; t[tot].L=t[x].L+d;t[tot].R=t[x].R; t[t[tot].ch[1]=t[x].ch[1]].fa=tot; t[t[x].ch[1]=tot].fa=x; pushup(tot); } t[x].val=get(t[x].L+d-1); t[x].L=t[x].R=0; }else if(t[x].R){ // cout<<" here "<<endl; t[x].val=get(t[x].R); t[x].L=t[x].R=0; // cout<<"val "<<t[x].val<<endl; } pushup(x); ret=t[x].val; splay(x,0); int son=t[x].ch[1]; if(!son){ t[rt[now]=t[x].ch[0]].fa=0; pushup(rt[now]);//cout<<"000 "<<t[0].sz<<endl; } else{ while(t[son].ch[0]) son=t[son].ch[0]; splay(son,rt[now]); t[t[son].ch[0]=t[x].ch[0]].fa=son; t[son].fa=0; pushup(son); rt[now]=son; // cout<<rt[now]<<" : "<<t[rt[now]].L<<" "<<t[rt[now]].R<<" "<<t[rt[now]].val<<" "<<t[rt[now]].ch[0]<<" "<<t[rt[now]].ch[1]<<" "<<t[rt[now]].sz<<endl; } return ret; } } void op(int x){ cout<<" from "<<t[x].fa<<endl; if(t[x].ch[0]) op(t[x].ch[0]); cout<<" back to "<<x<<" "<<endl; cout<<x<<endl; cout<<" go right "<<x<<" "<<endl; if(t[x].ch[1]) op(t[x].ch[1]); } int main(){ //freopen("data.in","r",stdin); //freopen("ut","w",stdout); rd(n);rd(m);rd(q); int x,y; for(reg i=1;i<=n;++i){ rt[i]=++tot; t[tot].L=1,t[tot].R=m-1; t[tot].sz=m-1; t[tot].fa=0; } rt[n+1]=++tot; t[tot].L=1,t[tot].R=n; t[tot].sz=n; while(q--){ rd(x);rd(y); ll id=0; if(y==m) now=n+1,id=query(rt[now],x); else now=x,id=query(rt[now],y); //cout<<" zero "<<t[0].sz<<endl; printf("%lld\n",id); // cout<<" over "<<rt[n+1]<<endl; // op(rt[n+1]); now=n+1; ins(rt[now],id); // //cout<<" ins "<<endl; // for(int i=1;i<=n+1;++i){ // cout<<i<<" : "<<rt[i]<<" : "<<t[rt[i]].sz<<" "<<t[rt[i]].L<<" "<<t[rt[i]].R<<endl; // } // if(y!=m){ now=n+1; id=query(rt[now],x); now=x; ins(rt[now],id); } // cout<<" after "<<endl; // for(int i=1;i<=n+1;++i){ // cout<<i<<" : "<<rt[i]<<" : "<<t[rt[i]].sz<<" "<<t[rt[i]].L<<" "<<t[rt[i]].R<<endl; // } // cout<<" fa "<<t[rt[n+1]].fa<<endl; // op(rt[n+1]); } return 0; }
无限之环(3h)
网络流神题。其实也不算太神。如果想到了网络流可能建图也不是什么很难想到的。
出错点:
1.数组开小了。。。。has[4],四位二进制数,少开一位。。。(这个导致开O2之后超级厌氧,全部输出-1WA掉,一定程度上转移了查错重心。。。)
2.提取四位二进制数的时候,习惯性地写成了while(tmp) has[++tot]=tmp%2,tmp>>=1;然鹅,最高位是0的话,没有提取完4位就break了。而且has没有memset,高位就存上了之前可能的1.。。。。导致WA死。。
其实开始找规律一点没错。。。。但是由于while高位0的锅,以为找错了,,,最后还打了暴力判断。。。。
规律版(240行):

#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int N=2000+2; const int inf=0x3f3f3f3f; int n,m,s,t; struct node{ int nxt,to; int w,v; }e[(5*N+4*N+N*6)*2]; int hd[5*N],cnt=1; void add(int x,int y,int w,int v){ e[++cnt].nxt=hd[x]; e[cnt].to=y; e[cnt].w=w; e[cnt].v=v; hd[x]=cnt; e[++cnt].nxt=hd[y]; e[cnt].to=x; e[cnt].w=0; e[cnt].v=-v; hd[y]=cnt; } int incf[5*N],dis[5*N]; int pre[5*N]; bool vis[5*N]; queue<int>q; bool spfa(){ while(!q.empty()) q.pop(); memset(vis,0,sizeof vis); memset(dis,inf,sizeof dis); dis[s]=0; incf[s]=inf; pre[s]=0; q.push(s); while(!q.empty()){ int x=q.front();q.pop(); vis[x]=0; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(e[i].w&&dis[y]>dis[x]+e[i].v){ dis[y]=dis[x]+e[i].v; pre[y]=i; incf[y]=min(e[i].w,incf[x]); if(!vis[y]){ vis[y]=1; q.push(y); } } } } if(dis[t]==inf) return false; return true; } int ans,maxflow; void upda(){ int x=t; while(pre[x]){ e[pre[x]].w-=incf[t]; e[pre[x]^1].w+=incf[t]; x=e[pre[x]^1].to; } ans+=incf[t]*dis[t]; maxflow+=incf[t]; //cout<<" ans "<<ans<<" "<<maxflow<<endl; } int has[10],tot; int mp[N][N]; int sz[N]; int num(int x,int y,int k){//5 is itself return ((x-1)*m+y-1)*5+k; } int main(){ rd(n);rd(m); s=0,t=n*m*5+1; for(reg i=1;i<=16;++i){ sz[i]=sz[i>>1]+(i&1); } int le=0,ri=0; for(reg i=1;i<=n;++i){ for(reg j=1;j<=m;++j){ rd(mp[i][j]); if((i+j)%2==0) add(s,num(i,j,5),sz[mp[i][j]],0),le+=sz[mp[i][j]]; else add(num(i,j,5),t,sz[mp[i][j]],0),ri+=sz[mp[i][j]]; } } if(le!=ri){ printf("-1");return 0; } for(reg i=1;i<=n;++i){ for(reg j=1;j<=m;++j){ for(reg l=1;l<=4;++l){ has[l]=(mp[i][j]>>(l-1))&1; } int now=num(i,j,5); tot=sz[mp[i][j]]; if((i+j)%2==0){ switch(tot){ case 0:{ break; } case 1:{ int pos=0; //cout<<" find "<<mp[i][j]<<" :: "<<has[1]<<" "<<has[2]<<" "<<has[3]<<" "<<has[4]<<endl; for(reg l=1;l<=4;++l) if(has[l]) { pos=l; } add(now,num(i,j,pos),1,0); add(now,num(i,j,pos%4+1),1,1); add(now,num(i,j,pos==1?4:pos-1),1,1); add(now,num(i,j,(pos+2<=4)?pos+2:pos-2),1,2); break; } case 2:{ if(mp[i][j]==5||mp[i][j]==10){ // cout<<" dkfjdf "<<endl; for(reg l=1;l<=4;++l){ if(has[l]) add(now,num(i,j,l),1,0); } }else{ for(reg l=1;l<=4;++l){ if(has[l]) { add(now,num(i,j,l),1,0); add(num(i,j,l),num(i,j,(l+2<=4)?l+2:l-2),1,1); } } } break; } case 3:{ for(reg l=1;l<=4;++l){ if(has[l]){ add(now,num(i,j,l),1,0); }else{ add(num(i,j,(l+1)<=4?l+1:l-3),num(i,j,l),1,1); add(num(i,j,(l+3)<=4?l+3:l-1),num(i,j,l),1,1); add(num(i,j,(l+2)<=4?l+2:l-2),num(i,j,l),1,2); } } break; } case 4:{ for(reg l=1;l<=4;++l){ add(now,num(i,j,l),1,0); } break; } } }else{ switch(tot){ case 0:{ break; } case 1:{ int pos=0; for(reg l=1;l<=4;++l) if(has[l]){ pos=l; } add(num(i,j,pos),now,1,0); add(num(i,j,pos%4+1),now,1,1); add(num(i,j,pos==1?4:pos-1),now,1,1); add(num(i,j,(pos+2<=4)?pos+2:pos-2),now,1,2); break; } case 2:{ if(mp[i][j]==5||mp[i][j]==10){ for(reg l=1;l<=4;++l){ if(has[l]) add(num(i,j,l),now,1,0); } }else{ for(reg l=1;l<=4;++l){ if(has[l]) { add(num(i,j,l),now,1,0); add(num(i,j,(l+2<=4)?l+2:l-2),num(i,j,l),1,1); } } } break; } case 3:{ for(reg l=1;l<=4;++l){ if(has[l]){ add(num(i,j,l),now,1,0); }else{ add(num(i,j,l),num(i,j,(l+1)<=4?l+1:l-3),1,1); add(num(i,j,l),num(i,j,(l+3)<=4?l+3:l-1),1,1); add(num(i,j,l),num(i,j,(l+2)<=4?l+2:l-2),1,2); } } break; } case 4:{ for(reg l=1;l<=4;++l){ add(num(i,j,l),now,1,0); } break; } } } if((i+j)%2==0){ if(i>1) add(num(i,j,1),num(i-1,j,3),1,0); if(i<n) add(num(i,j,3),num(i+1,j,1),1,0); if(j>1) add(num(i,j,4),num(i,j-1,2),1,0); if(j<m) add(num(i,j,2),num(i,j+1,4),1,0); } } } while(spfa()) upda(); //cout<<" maxflow "<<maxflow<<endl; if(maxflow!=le){ puts("-1");return 0; } printf("%d",ans); return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2018/12/14 21:08:15 */
暴力版(352行):

// luogu-judger-enable-o2 #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int N=20000+2; const int inf=0x3f3f3f3f; int n,m,s,t; struct node{ int nxt,to; int w,v; }e[(5*N+4*N+N*6)*2]; int hd[5*N],cnt=1; void add(int x,int y,int w,int v){ e[++cnt].nxt=hd[x]; e[cnt].to=y; e[cnt].w=w; e[cnt].v=v; hd[x]=cnt; e[++cnt].nxt=hd[y]; e[cnt].to=x; e[cnt].w=0; e[cnt].v=-v; hd[y]=cnt; } int incf[5*N],dis[5*N]; int pre[5*N]; bool vis[5*N]; queue<int>q; bool spfa(){ while(!q.empty()) q.pop(); memset(vis,0,sizeof vis); memset(dis,inf,sizeof dis); dis[s]=0; incf[s]=inf; pre[s]=0; q.push(s); while(!q.empty()){ int x=q.front();q.pop(); vis[x]=0; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(e[i].w&&dis[y]>dis[x]+e[i].v){ dis[y]=dis[x]+e[i].v; pre[y]=i; incf[y]=min(e[i].w,incf[x]); if(!vis[y]){ vis[y]=1; q.push(y); } } } } if(dis[t]==inf) return false; return true; } int ans,maxflow; void upda(){ int x=t; while(pre[x]){ e[pre[x]].w-=incf[t]; e[pre[x]^1].w+=incf[t]; x=e[pre[x]^1].to; } ans+=incf[t]*dis[t]; maxflow+=incf[t]; //cout<<" ans "<<ans<<" "<<maxflow<<endl; } int has[10],tot; int mp[2005][2005]; int sz[N]; int num(int x,int y,int k){//5 is itself return ((x-1)*m+y-1)*5+k; } int main(){ rd(n);rd(m); s=0,t=n*m*5+1; for(reg i=1;i<=16;++i){ sz[i]=sz[i>>1]+(i&1); } int le=0,ri=0; for(reg i=1;i<=n;++i){ for(reg j=1;j<=m;++j){ rd(mp[i][j]); if((i+j)%2==0) add(s,num(i,j,5),sz[mp[i][j]],0),le+=sz[mp[i][j]]; else add(num(i,j,5),t,sz[mp[i][j]],0),ri+=sz[mp[i][j]]; } } if(le!=ri){ printf("-1");return 0; } for(reg i=1;i<=n;++i){ for(reg j=1;j<=m;++j){ int tmp=mp[i][j]; tot=0; while(tmp){ has[++tot]=tmp%2;tmp/=2; } tot=sz[mp[i][j]]; int now=num(i,j,5); if((i+j)%2==0){ switch(tot){ case 0:{ break; } case 1:{ if(mp[i][j]==1){ add(now,num(i,j,1),1,0); add(now,num(i,j,2),1,1); add(now,num(i,j,3),1,2); add(now,num(i,j,4),1,1); }else if(mp[i][j]==2){ add(now,num(i,j,2),1,0); add(now,num(i,j,3),1,1); add(now,num(i,j,4),1,2); add(now,num(i,j,1),1,1); }else if(mp[i][j]==4){ add(now,num(i,j,3),1,0); add(now,num(i,j,2),1,1); add(now,num(i,j,1),1,2); add(now,num(i,j,4),1,1); }else if(mp[i][j]==8){ add(now,num(i,j,4),1,0); add(now,num(i,j,3),1,1); add(now,num(i,j,2),1,2); add(now,num(i,j,1),1,1); } break; } case 2:{ if(mp[i][j]==5||mp[i][j]==10){ // cout<<" dkfjdf "<<endl; // for(reg l=1;l<=4;++l){ // if(has[l]) add(now,num(i,j,l),1,0); // } if(mp[i][j]==5){ add(now,num(i,j,1),1,0); add(now,num(i,j,3),1,0); }else{ add(now,num(i,j,2),1,0); add(now,num(i,j,4),1,0); } break; } if(mp[i][j]==3){ add(now,num(i,j,1),1,0); add(now,num(i,j,2),1,0); add(num(i,j,1),num(i,j,3),1,1); add(num(i,j,2),num(i,j,4),1,1); } else if(mp[i][j]==6){ add(now,num(i,j,2),1,0); add(now,num(i,j,3),1,0); add(num(i,j,2),num(i,j,4),1,1); add(num(i,j,3),num(i,j,1),1,1); }else if(mp[i][j]==12){ add(now,num(i,j,3),1,0); add(now,num(i,j,4),1,0); add(num(i,j,3),num(i,j,1),1,1); add(num(i,j,4),num(i,j,2),1,1); }else{ add(now,num(i,j,1),1,0); add(now,num(i,j,4),1,0); add(num(i,j,1),num(i,j,3),1,1); add(num(i,j,4),num(i,j,2),1,1); } break; } case 3:{ if(mp[i][j]==7){ add(now,num(i,j,1),1,0); add(now,num(i,j,2),1,0); add(now,num(i,j,3),1,0); add(num(i,j,1),num(i,j,4),1,1); add(num(i,j,2),num(i,j,4),1,2); add(num(i,j,3),num(i,j,4),1,1); }else if(mp[i][j]==14){ add(now,num(i,j,4),1,0); add(now,num(i,j,2),1,0); add(now,num(i,j,3),1,0); add(num(i,j,4),num(i,j,1),1,1); add(num(i,j,2),num(i,j,1),1,1); add(num(i,j,3),num(i,j,1),1,2); }else if(mp[i][j]==13){ add(now,num(i,j,1),1,0); add(now,num(i,j,4),1,0); add(now,num(i,j,3),1,0); add(num(i,j,1),num(i,j,2),1,1); add(num(i,j,4),num(i,j,2),1,2); add(num(i,j,3),num(i,j,2),1,1); }else if(mp[i][j]==11){ add(now,num(i,j,1),1,0); add(now,num(i,j,2),1,0); add(now,num(i,j,4),1,0); add(num(i,j,1),num(i,j,3),1,2); add(num(i,j,2),num(i,j,3),1,1); add(num(i,j,4),num(i,j,3),1,1); } break; } case 4:{ for(reg l=1;l<=4;++l){ add(now,num(i,j,l),1,0); } break; } } }else{ switch(tot){ case 0:{ break; } case 1:{ if(mp[i][j]==1){ add(num(i,j,1),now,1,0); add(num(i,j,2),now,1,1); add(num(i,j,3),now,1,2); add(num(i,j,4),now,1,1); }else if(mp[i][j]==2){ add(num(i,j,2),now,1,0); add(num(i,j,3),now,1,1); add(num(i,j,4),now,1,2); add(num(i,j,1),now,1,1); }else if(mp[i][j]==4){ add(num(i,j,3),now,1,0); add(num(i,j,2),now,1,1); add(num(i,j,1),now,1,2); add(num(i,j,4),now,1,1); }else if(mp[i][j]==8){ add(num(i,j,4),now,1,0); add(num(i,j,3),now,1,1); add(num(i,j,2),now,1,2); add(num(i,j,1),now,1,1); } break; } case 2:{ if(mp[i][j]==5||mp[i][j]==10){ if(mp[i][j]==5){ add(num(i,j,1),now,1,0); add(num(i,j,3),now,1,0); }else{ add(num(i,j,2),now,1,0); add(num(i,j,4),now,1,0); } break; } if(mp[i][j]==3){ add(num(i,j,1),now,1,0); add(num(i,j,2),now,1,0); add(num(i,j,3),num(i,j,1),1,1); add(num(i,j,4),num(i,j,2),1,1); } else if(mp[i][j]==6){ add(num(i,j,2),now,1,0); add(num(i,j,3),now,1,0); add(num(i,j,4),num(i,j,2),1,1); add(num(i,j,1),num(i,j,3),1,1); }else if(mp[i][j]==12){ add(num(i,j,3),now,1,0); add(num(i,j,4),now,1,0); add(num(i,j,1),num(i,j,3),1,1); add(num(i,j,2),num(i,j,4),1,1); }else{ add(num(i,j,1),now,1,0); add(num(i,j,4),now,1,0); add(num(i,j,3),num(i,j,1),1,1); add(num(i,j,2),num(i,j,4),1,1); } break; } case 3:{ if(mp[i][j]==7){ add(num(i,j,1),now,1,0); add(num(i,j,2),now,1,0); add(num(i,j,3),now,1,0); add(num(i,j,4),num(i,j,1),1,1); add(num(i,j,4),num(i,j,2),1,2); add(num(i,j,4),num(i,j,3),1,1); }else if(mp[i][j]==14){ add(num(i,j,4),now,1,0); add(num(i,j,2),now,1,0); add(num(i,j,3),now,1,0); add(num(i,j,1),num(i,j,4),1,1); add(num(i,j,1),num(i,j,2),1,1); add(num(i,j,1),num(i,j,3),1,2); }else if(mp[i][j]==13){ add(num(i,j,1),now,1,0); add(num(i,j,4),now,1,0); add(num(i,j,3),now,1,0); add(num(i,j,2),num(i,j,1),1,1); add(num(i,j,2),num(i,j,4),1,2); add(num(i,j,2),num(i,j,3),1,1); }else if(mp[i][j]==11){ add(num(i,j,1),now,1,0); add(num(i,j,2),now,1,0); add(num(i,j,4),now,1,0); add(num(i,j,3),num(i,j,1),1,2); add(num(i,j,3),num(i,j,2),1,1); add(num(i,j,3),num(i,j,4),1,1); } break; } case 4:{ for(reg l=1;l<=4;++l){ add(num(i,j,l),now,1,0); } break; } } } if((i+j)%2==0){ if(i>1) add(num(i,j,1),num(i-1,j,3),1,0); if(i<n) add(num(i,j,3),num(i+1,j,1),1,0); if(j>1) add(num(i,j,4),num(i,j-1,2),1,0); if(j<m) add(num(i,j,2),num(i,j+1,4),1,0); } } } while(spfa()) upda(); // cout<<" maxflow "<<maxflow<<endl; if(maxflow!=le){ puts("-1");return 0; } printf("%d",ans); return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2018/12/14 21:08:15 */
BZOJ3779: 重组病毒(4h跨夜)
终于体会到数据结构的恶心之处了。。。。
调到神经错乱,内分泌失调,,,,,
开始以为LCT写挂,
和树点涂色对比发现没错!?
于是搞标程。。。
然后发现线段树输出的值不一样?!
线段树写挂了?
遂用“线段树1模板”对照,,,并没有错!?
然后考下来多个标程(TMD都什么鬼畜码风??!)
甚至一个标程先把所有dep-1,最后再+1,,,然后让我白白多调了1h的。。
然后终于找到小范围hack数据!
跟踪发现,多query几次就对了,不query就错了!?!?
线段树pushdown挂了?!!
仔细看看并没有!
难道数组RE?
仔细看看也没有!
跟踪线段树情况!
tr[3].sum:10->12偷偷变成了12?!!?
怀疑人生.gif
然后输出tr[3].sum跟踪。。
rotate+splay之后变成12?LCT和线段树有什么关系?!
发现rotate和splay之后有一个pushup!?!?!????!?!?!?!?!
我哩个去?!?!
pushup是线段树的同名操作,,,,,这题LCT不用,,,,习惯性地写了,,,,,
pushup几次应该不会出锅啊???
因为这个题,,一边access一边线段树区间加,一边pushup的话,可能一个打标记没有下放的区间,莫名被儿子pushup一下,sum值就变回原来的了!!!!!!!
哦!!
那,就这样吧。。。。
生无可恋.jpg

#include<bits/stdc++.h> #define reg register int #define il inline #define ls (x<<1) #define rs (x<<1|1) #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int N=100000+5; int n,m; struct bian{ int nxt,to; }e[2*N]; int hd[N],cnt; void add(int x,int y){ e[++cnt].nxt=hd[x]; e[cnt].to=y; hd[x]=cnt; } int dfn[N],dfn2[N],dep[N]; int f[N][20]; int rt,df,fdfn[N]; void dfs(int x,int fa,int d){ //cout<<" dfs "<<x<<" "<<fa<<" "<<d<<" "<<df<<endl; dep[x]=d; dfn[x]=++df; fdfn[df]=x; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; //cout<<" yy "<<y<<endl; if(y==fa) continue; f[y][0]=x; dfs(y,x,d+1); } dfn2[x]=df; } struct tree{ ll sum; ll add; }tr[4*N]; void pushup(int x){ tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum; } void build(int x,int l,int r){ if(l==r){ tr[x].sum=dep[fdfn[l]]; tr[x].add=0; return; } int mid=(l+r)/2; build(x<<1,l,mid); build(x<<1|1,mid+1,r); pushup(x); //cout<<" sum "<<l<<" "<<r<<" : "<<tr[x].sum<<endl; } void pushdown(int x,int l,int r){ if(!tr[x].add) return; int mid=(l+r)/2; //cout<<" pdpdpdpd "<<x<<endl; tr[x<<1].add+=tr[x].add; tr[x<<1].sum+=(ll)(mid-l+1)*tr[x].add; tr[x<<1|1].add+=tr[x].add; tr[x<<1|1].sum+=(ll)(r-mid)*tr[x].add; tr[x].add=0; } void upda(int x,int l,int r,int L,int R,ll c){ //cout<<" upda "<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<c<<" "<<tr[x].sum<<" "<<tr[x].add<<" ???? "<<tr[3].sum<<endl; if(L<=l&&r<=R){ tr[x].add+=c; tr[x].sum+=(ll)(r-l+1)*c; return; } pushdown(x,l,r); int mid=(l+r)/2; if(L<=mid) upda(ls,l,mid,L,R,c); if(mid<R) upda(rs,mid+1,r,L,R,c); pushup(x); // cout<<" back "<<l<<" "<<r<<" : "<<tr[x].sum<<" "<<tr[x<<1|1].sum<<" "<<tr[x<<1|1].sum+tr[x<<1].sum<<endl; } ll query(int x,int l,int r,int L,int R){ //cout<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tr[x].sum<<" "<<tr[x].add<<endl; if(L<=l&&r<=R){ return tr[x].sum; } pushdown(x,l,r);ll ret=0; int mid=(l+r)/2; 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; } int jump(int x){ int ret=rt; for(reg j=19;j>=0;--j) if(dep[f[ret][j]]>dep[x]) ret=f[ret][j]; return ret; } void wrk1(int x,ll c){//upda zishu if(!x) return; //cout<<" wrk "<<x<<" "<<c<<" nowrt "<<rt<<endl; if(x==rt){ // cout<<" rtrtrt "<<endl; upda(1,1,n,1,n,c); } // else if(dfn[rt]<=dfn[x]&&dfn[x]<=dfn2[rt]){ // upda(1,1,n,dfn[x],dfn2[x],c); // } else if(dfn[x]<=dfn[rt]&&dfn[rt]<=dfn2[x]){ // cout<<" suiergrgurhgurgh "<<endl; int son=jump(x); if(dfn[son]!=1)upda(1,1,n,1,dfn[son]-1,c); if(dfn2[son]!=n)upda(1,1,n,dfn2[son]+1,n,c); }else{ //cout<<" son "<<x<<" "<<dfn[x]<<" "<<dfn2[x]<<" "<<c<<endl; upda(1,1,n,dfn[x],dfn2[x],c); } } double wrk2(int x){//query zishu double ret=0; int sz=0; if(x==rt){ // cout<<" rtrtr "<<endl; return (double)query(1,1,n,1,n)/(double)n; }else if(dfn[x]<=dfn[rt]&&dfn[rt]<=dfn2[x]){ // cout<<" uifshgugh "<<endl; int son=jump(x); sz=dfn[son]-1+n-dfn2[son]; ret=(double)query(1,1,n,1,dfn[son]-1)+(double)query(1,1,n,dfn2[son]+1,n); return (double)ret/(double)sz; }else{ // cout<<" sqeure "<<" "<<query(1,1,n,dfn[x],dfn2[x])<<" "<<dfn2[x]-dfn[x]+1<<endl; return (double)query(1,1,n,dfn[x],dfn2[x])/((double)dfn2[x]-dfn[x]+1); } } struct node{ int fa,ch[2]; int r; }t[N]; bool nrt(int x){ return (t[t[x].fa].ch[0]==x)||(t[t[x].fa].ch[1]==x); } void rev(int x){ swap(t[x].ch[0],t[x].ch[1]); t[x].r^=1; } void pd(int x){ if(t[x].r){ rev(t[x].ch[0]);rev(t[x].ch[1]); t[x].r=0; } } void rotate(int x){ //cout<<" ro ??? "<<x<<" "<<tr[3].sum<<endl; int y=t[x].fa,d=t[y].ch[1]==x; t[t[y].ch[d]=t[x].ch[!d]].fa=y; if(nrt(y)) t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x; else t[x].fa=t[y].fa; t[t[x].ch[!d]=y].fa=x; //pushup(y); } int sta[N]; void splay(int x){ int y=x,z=0; sta[++z]=y; while(nrt(y)) y=t[y].fa,sta[++z]=y; while(z) pd(sta[z--]); //cout<<" splll ??? "<<tr[3].sum<<endl; while(nrt(x)){ y=t[x].fa,z=t[y].fa; if(nrt(y)){ rotate(((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x)); } rotate(x); } //pushup(x); } int pre(int x){ if(!x) return 0; pd(x); while(t[x].ch[0]) { pd(x); x=t[x].ch[0]; } return x; } void access(int x){ for(reg y=0;x;y=x,x=t[x].fa){ //cout<<" ssst ??? "<<tr[3].sum<<endl; splay(x); //cout<<" st ??? "<<tr[3].sum<<endl; int bc=pre(t[x].ch[1]); int pr=pre(y); // cout<<" access "<<x<<" "<<y<<" pre "<<pr<<" "<<bc<<endl; // cout<<" be ??? "<<tr[3].sum<<endl; wrk1(pr,-1); // cout<<" pr ??? "<<tr[3].sum<<endl; wrk1(bc,1); //cout<<" bc ??? "<<tr[3].sum<<endl; t[x].ch[1]=y; } } void makert(int x){ access(x);splay(x);rev(x); } int main(){ rd(n);rd(m); int x,y; for(reg i=1;i<n;++i){ rd(x);rd(y); add(x,y);add(y,x); }//cout<<" ahah "<<endl; dfs(1,0,1); dep[0]=-1; for(reg i=1;i<=n;++i){ t[i].fa=f[i][0]; } for(reg j=1;j<=19;++j){ for(reg i=1;i<=n;++i){ f[i][j]=f[f[i][j-1]][j-1]; } } build(1,1,n); //cout<<"---------------------------"<<dep[15]<<" : "<<dfn[15]<<" "<<dfn2[15]<<" "<<query(1,1,n,dfn[15],dfn2[15])<<endl; rt=1; char s[233]; while(m--){ scanf("%s",s+1); rd(x); //cout<<" -----------------------rtsum "<<tr[1].sum<<" "<<endl; if(s[3]=='Q'){//cout<<" t3 "<<query(1,1,n,dfn[3],dfn[3])<<" t4 "<<query(1,1,n,dfn[4],dfn[4])<<" t5 "<<query(1,1,n,dfn[5],dfn[5])<<" t6 "<<query(1,1,n,dfn[6],dfn[6])<<" t7 "<<query(1,1,n,dfn[7],dfn[7])<<endl; printf("%.10lf\n",wrk2(x)); }else if(s[3]=='L'){ //cout<<"??? "<<tr[3].sum<<endl; access(x); }else if(s[3]=='C'){ makert(x); rt=x; } } return 0; } } signed main(){ // freopen("4.in","r",stdin); // freopen("my.out","w",stdout); Miracle::main(); return 0; }
[九省联考2018]秘密袭击coat(研究4h题解)
官方题解思路挺新奇的。
Chef and Sad Pairs(3h)
圆方树+虚树+树上差分的总和题目
注意错误点
「LibreOJ NOI Round #1」验题(目前最长代码(+注释)400行)
动态DP好久以来第一次写,还是线段树维护轻儿子那种。

#include<bits/stdc++.h> #define reg register int #define il inline #define mid ((l+r)>>1) #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){ char ch;x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int N=1e6+6; const int M=4e6+5; int n; int b[N][2]; int a[N],I; int ori[N]; ll k; int hd[N],cnt; int bian[N][2]; struct node{ int nxt,to; }e[2*N]; void addedge(int x,int y){ e[++cnt].nxt=hd[x]; e[cnt].to=y; hd[x]=cnt; } ll mul(const ll &a,const ll &b){ if(!a||!b) return 0; if(a>k+1||b>k+1) return k+2; return __builtin_clzll(a)+__builtin_clzll(b)<66?k+2:a*b; } ll add(const ll &a,const ll &b){ return a+b>k+1?k+2:a+b; } struct mat{ ll a[2][2]; void clear(){memset(a,0,sizeof a);} void pre(){a[0][0]=1;a[1][1]=1;a[0][1]=a[1][0]=0;} void init(){a[0][0]=a[1][0]=a[0][1]=1;a[1][1]=0;} mat operator *(const mat&b){ mat c; // for(reg i=0;i<1;++i){ // for(reg k=0;k<1;++k){ // for(reg j=0;j<1;++j){ // c.a[i][j]=add(c.a[i][j],mul(a[i][k],b.a[k][j])); // } // } // } c.a[0][0]=add(mul(a[0][0],b.a[0][0]),mul(a[0][1],b.a[1][0])); c.a[0][1]=add(mul(a[0][0],b.a[0][1]),mul(a[0][1],b.a[1][1])); c.a[1][0]=add(mul(a[1][0],b.a[0][0]),mul(a[1][1],b.a[1][0])); c.a[1][1]=add(mul(a[1][0],b.a[0][1]),mul(a[1][1],b.a[1][1])); return c; } void op(){ cout<<a[0][0]<<" "<<a[0][1]<<endl; cout<<a[1][0]<<" "<<a[1][1]<<endl; } }st[N],base,nowdp; int dfn[N],top[N],dep[N],son[N],sz[N],fa[N]; int fdfn[N]; int low[N]; int df; int totson[N]; int num[N];//i is i's fa's num[i] son int in[N];//0 not 1 yes ll f[N][2]; namespace seg1{//get lian int tot; int ls[M],rs[M]; mat data[M]; struct tr1{ int ss,nd; int rt; void pushup(int x){ // cout<<"pushup "<<x<<" "<<ls[x]<<" "<<rs[x]<<endl; // data[rs[x]].op(); // data[ls[x]].op(); data[x]=data[rs[x]]*data[ls[x]]; // cout<<endl; // data[x].op(); } mat get(){ return data[rt]; } void build(int &x,int l,int r){ x=++tot; // cout<<" x "<<x<<" "<<l<<" "<<r<<endl; if(l==r){ // cout<<"l==r "<<fdfn[l]<<endl; // st[fdfn[l]].op(); data[x]=st[fdfn[l]];return; } build(ls[x],l,mid);build(rs[x],mid+1,r); pushup(x); // cout<<" bac "<<x<<" "<<endl; // data[x].op(); } void chan(int p,ll c0,ll c1){ upda(rt,ss,nd,p,c0,c1); } mat que(int L,int R){ return query(rt,ss,nd,L,R); } mat query(int x,int l,int r,int L,int R){ if(L<=l&&r<=R){ return data[x]; } mat ret; ret.pre(); if(mid<R) ret=ret*query(rs[x],mid+1,r,L,R); if(L<=mid) ret=ret*query(ls[x],l,mid,L,R); return ret; } void upda(int x,int l,int r,int p,ll c0,ll c1){ if(l==r){ data[x].a[0][0]=c0; data[x].a[1][0]=c0; data[x].a[0][1]=c1; return; } if(p<=mid) upda(ls[x],l,mid,p,c0,c1); else upda(rs[x],mid+1,r,p,c0,c1); pushup(x); } }; }using seg1::tr1; tr1 t1[N]; int mem[N]; namespace seg2{//get son int tot; int ls[M],rs[M]; ll s0[M],s1[M]; struct tr2{ int sz,rt; void pushup(int x){ s0[x]=mul(s0[ls[x]],s0[rs[x]]); s1[x]=mul(s1[ls[x]],s1[rs[x]]); } void build(int &x,int l,int r){ x=++tot; if(l==r){ s0[x]=f[mem[l]][0]+f[mem[l]][1]; s1[x]=f[mem[l]][0]; return; } build(ls[x],l,mid);build(rs[x],mid+1,r); pushup(x); } void chan(int p,ll c0,ll c1){ upda(rt,1,sz,p,c0,c1); } void upda(int x,int l,int r,int p,ll c0,ll c1){ if(l==r){ s0[x]=c0; s1[x]=c1; return; } if(p<=mid) upda(ls[x],l,mid,p,c0,c1); else upda(rs[x],mid+1,r,p,c0,c1); pushup(x); } void spe(int &x){ x=++tot; s0[x]=1;s1[x]=1; } ll get0(){ // cout<<" rtrt "<<rt<<endl; return s0[rt]; } ll get1(){ return s1[rt]; } }; }using seg2::tr2; tr2 t2[N]; int sta[N],tp; void dfs1(int x,int d){ // cout<<"dfs1 "<<x<<" "<<d<<endl; dep[x]=d; sz[x]=1; if(!in[x])f[x][0]=1; else f[x][1]=1; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(y==fa[x]) continue; fa[y]=x; dfs1(y,x); sz[x]+=sz[y]; if(sz[y]>sz[son[x]]) son[x]=y; } } void dfs2(int x){ // cout<<" dfs2 "<<x<<" "<<son[x]<<endl; dfn[x]=++df; sta[++tp]=x; fdfn[df]=x; if(!top[x]) top[x]=x; if(son[x]) top[son[x]]=top[x],++totson[x],dfs2(son[x]); st[x].init(); for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(y==son[x]) continue; if(y==fa[x]) continue; num[y]=totson[x]; ++totson[x]; dfs2(y); if(in[x]){ st[x].a[0][1]*=(f[y][0]); }else{ st[x].a[0][0]*=(f[y][0]+f[y][1]); st[x].a[1][0]*=(f[y][0]+f[y][1]); } } if(in[x]) st[x].a[0][0]=st[x].a[1][0]=0; else st[x].a[0][1]=0; // cout<<" mat-------------------------------"<<x<<endl; //st[x].op(); // t1[top[x]].ss=dfn[top[x]]; // t1[top[x]].nd=dfn[x]; // t1[top[x]].build(t1[top[x]].rt,t1[top[x]].ss,t1[top[x]].nd); // if(top[x]==x){ // cout<<" zhong ss "<<x<<" nd "<<sta[tp]<<endl; t1[x].ss=dfn[x]; t1[x].nd=dfn[sta[tp]]; t1[x].build(t1[x].rt,t1[x].ss,t1[x].nd); // cout<<" t1rt "<<endl;t1[x].get().op(); int z; do{ z=sta[tp]; --tp; }while(z!=x); } if(totson[x]==0){//leaf t2[x].spe(t2[x].rt); // cout<<"gen "<<t2[x].rt<<endl; } else if(totson[x]==1){ t2[x].spe(t2[x].rt); } else if(totson[x]>1){ // cout<<" has son "<<x<<" "<<totson[x]<<endl; int lp=0; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(y==fa[x]||y==son[x]) continue; mem[++lp]=y; } t2[x].sz=lp; t2[x].build(t2[x].rt,1,lp); } } mat upda(int x){ mat ret; ret.clear(); // cout<<" upda "<<x<<" in "<<in[x]<<endl; while(x){ if(in[x]==0){//must not // cout<<"get0 "<<t2[x].rt<<" "<<t2[x].get0()<<endl; t1[top[x]].chan(dfn[x],t2[x].get0(),0); }else if(in[x]==1){//must yes t1[top[x]].chan(dfn[x],0,t2[x].get1()); }else{//either // cout<<" g0 g1 "<<t2[x].get0()<<" "<<t2[x].get1()<<endl; t1[top[x]].chan(dfn[x],t2[x].get0(),t2[x].get1()); } // if(x==1)t1[top[x]].que(2,3).op(),t1[top[x]].que(1,1).op(); // cout<<" difd "<<endl; // t1[top[x]].get().op(); ret=base*t1[top[x]].get(); x=top[x]; if(fa[x]){ t2[fa[x]].chan(num[x],add(ret.a[0][0],ret.a[0][1]),ret.a[0][0]); } x=fa[x]; } // cout<<"ret "<<ret.a[0][0]<<" "<<ret.a[0][1]<<endl; return ret; } int main(){ rd(n); scanf("%lld",&k); base.a[0][0]=1; for(reg i=1;i<n;++i) rd(b[i][0]),++b[i][0]; for(reg i=1;i<n;++i) { rd(b[i][1]); ++b[i][1]; addedge(b[i][0],b[i][1]); addedge(b[i][1],b[i][0]); } rd(I); for(reg i=1;i<=I;++i) rd(a[i]),++a[i],in[a[i]]=1,ori[a[i]]=1; sort(a+1,a+I+1); if(k==0){ for(reg i=1;i<=I;++i){ printf("%d ",a[i]-1); } return 0; } dfs1(1,1); // cout<<" after dfs1 "<<endl; dfs2(1); // cout<<" after dfs2 "<<endl; // cout<<nowdp.a[0][0]+nowdp.a[0][1]<<endl; int lcp=I;//warning!! num ll remain=k; for(reg i=a[lcp]+1;i<=n;++i){ in[i]=2; nowdp=upda(i); } ll tot=add(nowdp.a[0][0],nowdp.a[0][1]); int lp=0; //has=0; // cout<<" after last zero "<<endl; if(tot-1<remain){ remain-=max(1LL*0,tot-1); int ptr=a[lcp]-1; for(;lcp;--lcp){ // cout<<"lcp "<<lcp<<endl; in[a[lcp]]=0; nowdp=upda(a[lcp]); tot=add(nowdp.a[0][0],nowdp.a[0][1]); // cout<<"tot "<<tot<<endl; if(tot-1<remain){ remain-=tot-1; in[a[lcp]]=2; nowdp=upda(a[lcp]); }else{ break; } ptr=a[lcp]-1; while(ptr&&ori[ptr]!=1){ in[ptr]=2; nowdp=upda(ptr); --ptr; } } if(!lcp){ return 0; } } // cout<<" after lcp "<<lcp<<endl; // else{ // lp=a[lcp]+1; // for(reg i=lp;i<=n;++) // } lp=a[lcp]+1; for(reg i=lp;i<=n;++i){ // cout<<" ii "<<i<<" ---------------- "<<remain<<endl; in[i]=1; nowdp=upda(i); tot=add(nowdp.a[0][0],nowdp.a[0][1]); // cout<<" tot "<<tot<<endl; if(tot<remain){ remain-=tot; in[i]=0; nowdp=upda(i); }else{ --remain; } if(remain==0) break; } for(reg i=1;i<=n;++i){ if(in[i]==1){ printf("%d ",i-1); } } return 0; } } signed main(){ // freopen("61.in","r",stdin); // freopen("my.out","w",stdout); Miracle::main(); return 0; } /* Author: *Miracle* Date: 2019/2/20 11:04:52 */
CF704E Iron Man
写计算几何还是真的恶心,,,
前后经历4h还是不能调过去。
orz了标程,发现,存线段还是存起点终点斜率比较好,保留k*x+b,b会损失精度。
求交的话,就当做是追及问题
[国家集训队]JZPSTR
bitset处理0~9的出现情况,
插入删除查询都是移位操作。
4h写了6个k,怒拿倒数第一

// luogu-judger-enable-o2 #include<bits/stdc++.h> #define reg register int #define il inline #define fi first #define se second #define mk(a,b) make_pair(a,b) #define numb (ch^'0') #define pb push_back #define solid const auto & #define enter cout<<endl #define pii pair<int,int> using namespace std; typedef long long ll; template<class T>il void rd(T &x){ char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);} template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');} template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');} template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Modulo{ const int mod=998244353; il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;} il int sub(int x,int y){return ad(x,mod-y);} il int mul(int x,int y){return (ll)x*y%mod;} il void inc(int &x,int y){x=ad(x,y);} il void inc2(int &x,int y){x=mul(x,y);} il int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;} template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);} template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);} } //using namespace Modulo; #define ull unsigned long long namespace Miracle{ const int w=64; pii be(int x){ if(x<0) return mk(-1,-233); return mk(x/w,x%w); } int sz(ull x){ return __builtin_popcountll(x); } ull pw[w+2]; ull all[w+2]; char s[2000000+3]; struct bit{ vector<ull>f; il ull &operator[](const int &x){return f[x];} il const ull &operator[](const int &x) const {return f[x];} void resize(int n){ f.resize(n/w+1); } void set(int x){ pii now=be(x); //cout<<" set "<<x<<" sz "<<f.size()<<" : "<<now.fi<<" "<<now.se<<endl; f[now.fi]|=pw[now.se]; } void reset(int x){ pii now=be(x); if((f[now.fi]>>now.se)&1) f[now.fi]-=pw[now.se]; } int size() const{ return f.size(); } int count(){ int ret=0; for(solid x:f){ret+=sz(x);}return ret; } ull val(int l,int r){ //cout<<" val "<<l<<" "<<r<<endl; if(l>r) return 0; pii L=be(l),R=be(r); //cout<<" L "<<L.fi<<" "<<L.se<<" R "<<R.fi<<" "<<R.se<<endl; if(L.fi>=(int)f.size()) return 0; if(R.fi<0) return 0; if(R.fi>=(int)f.size()){ R=mk(f.size()-1,w-1); } if(L.fi<0){ L=mk(0,0); } if(L.fi==R.fi){ ull v=f[L.fi]; //cout<<" same "<<v<<" "<<(v&all[R.se+1])<<endl; return (((v&all[R.se+1])-(v&(all[L.se])))>>L.se); }else{ //ull ret=((f[R.fi]&all[R.se+1])<<(w-L.se))+((f[L.fi]-(f[L.fi]&(all[L.se])))>>L.se); //cout<<" ret "<<ret<<endl; return ((f[R.fi]&all[R.se+1])<<(w-L.se))+((f[L.fi]-(f[L.fi]&(all[L.se])))>>L.se); } } bit friend operator <<(bit &a,int c){ bit f;f.f.resize(a.f.size()); for(reg i=0;i<a.size();++i){ f[i]=a.val(i*w+c,i*w+w-1+c); } return f; } bit friend operator >>(bit &a,int c){ bit f;f.f.resize(a.f.size()); for(reg i=a.size()-1;i>=0;--i){ f[i]=a.val(i*w-c,i*w+w-1-c); } return f; } void shift(int tp,int st,int c){ //cout<<" shift "<<st<<" "<<c<<endl; if(tp==0){//go left pii pos=be(st-c); for(reg i=pos.fi;i<(int)f.size();++i){ int l=i*w+c,r=i*w+w-1+c; if(i==pos.fi){ f[i]=(f[i]&all[pos.se])+(val(st,r)<<pos.se); } else{ f[i]=val(l,r); } } resize(f.size()*w-c); }else{//go right pii pos=be(st); resize(f.size()*w+c); for(reg i=(int)f.size()-1;i>=0;--i){ int l=i*w-c,r=i*w+w-1-c; ull tmp; if(r<st) tmp=0; else if(l<st){ tmp=val(st,r); }else{ tmp=val(l,r); } if(i==pos.fi){ if(!tmp) f[i]=(f[i]&all[pos.se]); else f[i]=(f[i]&all[pos.se])+(tmp<<(pos.se+c)); break; } else{ if(r<st) f[i]=0; else if(l<st){ f[i]=val(st,r)<<(st-l); }else{ f[i]=val(l,r); } } } } } bit friend operator &(const bit &a,const bit &b){ bit c=a; for(reg i=0;i<(int)c.size();++i){ c.f[i]&=b.f[i]; } return c; } void op(){ //cout<<" op "<<f.size()<<endl; for(reg i=0;i<f.size();++i){ for(reg j=0;j<w;++j){ cout<<((f[i]>>j)&1); } } //cout<<endl; } bit get(int l,int r){ //cout<<" get "<<l<<" "<<r<<endl; int len=r-l+1; bit g;g.resize(len); for(reg i=0;i<(int)g.size();++i){ int nl=i*w+l,nr=i*w+w-1+l; //cout<<" gegeeg "<<i<<endl; g[i]=val(nl,min(nr,r)); } return g; } }f[10],h[10],as; int vis[10]; int main(){ pw[0]=1; for(reg i=1;i<=w;++i){ pw[i]=pw[i-1]*2; all[i]=pw[i]-1; } int m; rd(m); int op,l,r,x; while(m--){ rd(op); if(op==0){ rd(x);scanf("%s",s+1); int len=strlen(s+1); //cout<<" len "<<len<<endl; for(reg i=0;i<=9;++i){ f[i].shift(1,x,len); } ///cout<<" after shift "<<endl; ///for(reg i=0;i<=9;++i){ /// cout<<"num i "<<i<<endl; /// f[i].op(); //} for(reg i=1;i<=len;++i){ int c=s[i]-'0'; f[c].set(x+i-1); } //cout<<" end set"<<endl; //for(reg i=0;i<=9;++i){ // cout<<"num i "<<i<<endl; // f[i].op(); //} }else if(op==1){ rd(l);rd(r); for(reg i=0;i<=9;++i){ f[i].shift(0,r,r-l); } }else{ rd(l);rd(r);--r;scanf("%s",s+1); int len=strlen(s+1); memset(vis,0,sizeof vis); as.resize(r-l+1); for(reg i=0;i<as.size();++i){ as[i]=all[w]; } //cout<<" count "<<as.count()<<endl; //as.op(); for(reg i=1;i<=len;++i){ //cout<<" -------- "<<i<<endl; int c=s[i]-'0'; if(!vis[c]){ vis[c]=1; h[c]=f[c].get(l,r); } //cout<<" h[c] "<<h[c].count()<<endl; //h[c].op(); bit lp=h[c]; lp=lp<<(i-1); //cout<<" lp "<<lp.count()<<endl; //lp.op(); as=as&(lp); //cout<<" count "<<as.count()<<endl; //as.op(); } printf("%d\n",as.count()); } } return 0; } } signed main(){ // freopen("my.out","w",stdout); Miracle::main(); return 0; } /* Author: *Miracle* */
注意(1<<x)1是int,还是预处理pw[i]=2^i比较稳妥。