@shixinyi
2018-01-04T12:46:34.000000Z
字数 30368
阅读 654
OI
相当于%9,但是余0的是9。
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longll T,l,r;ll aa;char cc;ll read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}ll cnt[20];ll get_ans(ll x) {if(x<=0) return x+1;ll rs=1;//0for(ll i=1;i<=9;++i) rs+=(cnt[i]=(x-i*i+i*9)/(i*9));//用循环简单一些rs-=cnt[1]/8;rs-=cnt[2]/7;rs-=cnt[3]/2;rs-=cnt[4]/5;return rs;}int main() {T=read();while(T--) {l=read();r=read();printf("%lld\n",get_ans(r)-get_ans(l-1));}return 0;}
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;const int maxn=1e4+10,maxm=4e5+10,INF=0x3f3f3f3f;//maxm开小了int n,m,ans=INF;int aa;char cc;int read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}int fir[maxn],nxt[maxm],to[maxm],v[maxm],e=0;void add(int x,int y,int z) {to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;}int dis[maxn],zz[maxn];bool vis[maxn];int spfa(int st) {int s=1,t=0,x,y,z,tot=1;memset(dis,0x3f3f3f3f,sizeof(dis));dis[st]=0;vis[st]=1;zz[++t]=st;while(tot--) {x=zz[s];s=(s+1)%maxn;vis[x]=0;for(y=fir[x];y;y=nxt[y]) {if(dis[z=to[y]]<=dis[x]+v[y]||(x==st&&z==1)) continue;dis[z]=dis[x]+v[y];if(!vis[z]) {vis[z]=1;tot++;if(dis[z]<=dis[zz[s]]) {s=(s-1+maxn)%maxn;zz[s]=z;}else {t=(t+1)%maxn;zz[t]=z;}}}}return dis[1];}int main() {n=read(); m=read();int x,y,z1,z2;for(int i=1;i<=m;++i) {x=read();y=read();z1=read();z2=read();if(x>y) swap(x,y),swap(z1,z2);add(x,y,z1); add(y,x,z2);}for(y=fir[1];y;y=nxt[y]) ans=min(ans,spfa(to[y])+v[y]);printf("%d",ans);return 0;}
正向跑一次,反向跑一次,求交点。
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<set>using namespace std;#define ll long longconst int maxn=8e5+10,INF=1e7;int n,m,cse,tot1,tot2,p[maxn],tt,S,T,ok;bool vis[2*maxn];int aa;char cc;int read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}struct Node{int x,y,p;}node[2*maxn];bool cmp1(int a,int b) {return node[a].x==node[b].x? node[a].y<node[b].y : node[a].x<node[b].x;}bool cmp2(int a,int b) {return node[a].y==node[b].y? node[a].x<node[b].x : node[a].y<node[b].y;}int fir[4*maxn],nxt[4*maxn],to[4*maxn],e;void add(int x,int y) {// printf("add: %d %d\n",x,y);to[++e]=y;nxt[e]=fir[x];fir[x]=e;to[++e]=x;nxt[e]=fir[y];fir[y]=e;}void init() {tot1=read();tot2=read();tt=tot1+tot2;S=tt*2+1;T=S+1;for(int i=1;i<=tot1;++i) {node[i].x=read();node[i].y=read();node[i].p=0;}for(int i=1;i<=tot2;++i) {node[i+tot1].x=read();node[i+tot1].y=read();node[i+tot1].p=1;}node[S].x=1;node[S].y=0;node[T].x=n;node[T].y=m+1;}void get_edge() {for(int i=1;i<=tt;++i) p[i]=i;sort(p+1,p+tt+1,cmp1);for(int i=2;i<=tt;++i) if(node[p[i-1]].x==node[p[i]].x) add(p[i-1]+tt,p[i]);if(node[p[1]].x==1) add(S,p[1]);if(node[p[tt]].x==n) add(p[tt]+tt,T);for(int i=1;i<=tt;++i) p[i]=i;sort(p+1,p+tt+1,cmp2);for(int i=2;i<=tt;++i) if(node[p[i-1]].y==node[p[i]].y)add(p[i-1]+tt*(int)(node[p[i-1]].p==0),p[i]+tt*(int)(node[p[i]].p==1));}int get_d(int tox,int x) {if(!x) return (tox+1)%4+1;return 5-tox;}struct Line{int x,y,z;}li[5][2*maxn];int tot[5];//0~3bool cmp3(const Line& a,const Line& b) {return a.z==b.z? a.x<b.x:a.z<b.z;//写反了}void bld1(int x,int y,int p) {p=(p-1)<<1;if(x<S&&x>tt) x-=tt;int ff=(node[x].y==node[y].y);int s=(++tot[p+=ff]);if(!ff) li[p][s].x=node[x].y,li[p][s].y=node[y].y,li[p][s].z=node[x].x;else li[p][s].x=node[x].x,li[p][s].y=node[y].x,li[p][s].z=node[x].y;}void bld2(int x,int tox,int p) {p=(p-1)<<1;if(x<S&&x>tt) x-=tt;int ff=tox/3;int s=(++tot[p+=ff]);if(!ff) li[p][s].z=node[x].x;else li[p][s].z=node[x].y;if(tox==1) li[p][s].x=node[x].y,li[p][s].y=m+1;else if(tox==2) li[p][s].y=node[x].y,li[p][s].x=0;else if(tox==3) li[p][s].y=node[x].x,li[p][s].x=0;else li[p][s].x=node[x].x,li[p][s].y=n+1;}bool dfs(int pos,int tox,int p) {vis[pos]=1;int y,z,g,d,ok=0;for(y=fir[pos];y;y=nxt[y]) {if(vis[z=to[y]]) continue;if((z==T&&p==1)||(z==S&&p==2)) return 1;else if(z==T||z==S) {ok=0; break;}ok=1; g=(z-1)%tt+1;d=get_d(tox,node[g].p);bld1(pos,g,p);if(dfs(z,d,p)) return 1;}vis[pos]=0;if(!ok) bld2(pos,tox,p);return 0;}set<ll> Gpl[2],Gmi[2];set<ll>::iterator it1,it2;int sz[3*maxn];int q(int pos) {int rs=0;while(pos) {rs+=sz[pos];pos-=(pos&-pos);}return rs;}void chge(int pos,int x) {while(pos<=m) {sz[pos]+=x;pos+=(pos&-pos);}}int ans,ansx,ansy;void rn(int x,int l,int r) {int lx=l-1,rx=r,t=q(l-1),mid;while(lx<rx-1) {mid=(lx+rx)>>1;if(q(mid)>t) rx=mid;else lx=mid;}if(x<ansx||(x==ansx&&rx<ansy)) {ansx=x;ansy=rx;}ok=1;}void get_ans() {for(int i=0;i<4;++i) {for(int j=1;j<=tot[i];++j) {if(li[i][j].x>li[i][j].y) swap(li[i][j].x,li[i][j].y);++li[i][j].x;--li[i][j].y;if(li[i][j].x>li[i][j].y) li[i][j].z=INF;//z写的x}}ans=0;sort(li[0]+1,li[0]+tot[0]+1,cmp3);sort(li[2]+1,li[2]+tot[2]+1,cmp3);while(tot[0]&&li[0][tot[0]].z==INF) tot[0]--;while(tot[2]&&li[2][tot[2]].z==INF) tot[2]--;Gpl[0].clear();Gmi[0].clear();Gpl[1].clear();Gmi[1].clear();//忘记clearfor(int i=1;i<4;i+=2) {for(int j=1;j<=tot[i];++j) {if(li[i][j].z==INF) continue;Gpl[i>2].insert((ll)li[i][j].z+(ll)li[i][j].x*INF);Gmi[i>2].insert((ll)li[i][j].z+(ll)(li[i][j].y+1)*INF);//应该以x或y为第一关键字}}memset(sz,0,sizeof(sz));int pos=1;it1=Gpl[1].begin();it2=Gmi[1].begin();int l,r,now;ok=0;for(int i=1;i<=n&&pos<=tot[0];++i) {while(it1!=Gpl[1].end()&&(*it1)/(ll)INF==i) chge((*it1)%(ll)INF,1),it1++;while(it2!=Gmi[1].end()&&(*it2)/(ll)INF==i) chge((*it2)%(ll)INF,-1),it2++;//lll=0;r=0;while(pos<=tot[0]&&li[0][pos].z==i) {l=max(l,li[0][pos].x);r=max(l-1,li[0][pos].y);if(l<=r) {ans+=(now=q(r)-q(l-1));if(!ok&&now) rn(i,l,r);}l=r+1; pos++;}}memset(sz,0,sizeof(sz));pos=1;it1=Gpl[0].begin();it2=Gmi[0].begin(); ok=0;for(int i=1;i<=n&&pos<=tot[2];++i) {while(it1!=Gpl[0].end()&&(*it1)/(ll)INF==i) chge((*it1)%(ll)INF,1),it1++;while(it2!=Gmi[0].end()&&(*it2)/(ll)INF==i) chge((*it2)%(ll)INF,-1),it2++;l=0;r=0;while(pos<=tot[2]&&li[2][pos].z==i) {l=max(l,li[2][pos].x);r=max(l-1,li[2][pos].y);if(l<=r) {ans+=(now=q(r)-q(l-1));if(!ok&&now) rn(i,l,r);}l=r+1; pos++;}}}void clear() {memset(fir,0,sizeof(fir));memset(nxt,0,sizeof(nxt));memset(vis,0,sizeof(vis));e=0;ansx=n+1;ansy=m+1;tot[0]=tot[1]=tot[2]=tot[3]=0;}int main() {while(scanf("%d%d",&n,&m)==2) {printf("Case %d: ",++cse);clear(); init();get_edge();if(dfs(S,1,1)||dfs(T,2,2)||(n==1&&!tot1&&!tot2)) printf("0");//n==1的情况直接射出去else if(n==1) printf("impossible");else {get_ans();if(ans) printf("%d %d %d",ans,ansx,ansy);else printf("impossible");}printf("\n");}return 0;}
直接枚举z,然后用并查集维护联通快,跑最短路。
因为中间有一些已经连好的边,所以不能直接只判断从S所在联通块直接到T所在联通块的最短距离
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<queue>using namespace std;#define ll long long#define db doubleconst int maxn=400+10,maxm=5e4+10;const db INF=1e17;ll n,m,S,T,p[maxn],fa[maxn],h,now;db d[maxn][maxn],ans=INF;bool vis[maxn];ll aa,ff;char cc;ll read() {aa=0;cc=getchar();ff=1;while(cc<'0'||cc>'9') {if(cc=='-') ff=-1;cc=getchar();}while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa*ff;}struct Node{ll x,y,z,k;int id;}node[maxn];bool cmp(const Node& a,const Node& b) {return a.z < b.z;}db pf(db x) {return x*x;}db get_dis(int a,int b) {return sqrt(pf(node[a].x-node[b].x)+pf(node[a].y-node[b].y)+pf(node[a].z-node[b].z));}int fir[maxn],nxt[2*maxm],to[2*maxm],e=0;void add(int x,int y) {to[++e]=y;nxt[e]=fir[x];fir[x]=e;to[++e]=x;nxt[e]=fir[y];fir[y]=e;}int find(int x) {return fa[x]==x? x:fa[x]=find(fa[x]);}struct Di{int x,p;db d;Di(){}Di(int x,int p,db d):x(x),p(p),d(d){}bool operator <(const Di& b) const{return d > b.d;}};priority_queue<Di> G;db dis[maxn][2];void get_ans(int pos) {for(int i=1;i<=n;++i) dis[i][0]=dis[i][1]=INF;dis[S][0]=0; G.push(Di(S,0,0));int x,y,t; db rs=(db)now*0.5,ad,dx;//dx开成intwhile(!G.empty()) {x=G.top().x; t=G.top().p; dx=G.top().d; G.pop();//忘记popif(dx!=dis[x][t]) continue;for(y=1;y<=pos;++y) {if(find(y)!=find(S)&&find(y)!=find(T)) ad=(db)node[y].k*0.5;//忘记(db)else ad=0;if(d[x][y]==0) {if(dis[y][0]<=dx+ad) continue;dis[y][0]=dx+ad;G.push(Di(y,0,dis[y][0]));}else if(node[y].k&&node[x].k>t&&dis[y][1]>dx+d[x][y]+ad-1) {//t与dx搞混dis[y][1]=dx+d[x][y]+ad-1;G.push(Di(y,1,dis[y][1]));}}}ans=min(ans,min(dis[T][0],dis[T][1])+rs);}int main() {n=read();m=read();for(int i=1;i<=n;++i) {node[i].x=read();node[i].y=read();node[i].z=read();node[i].k=read();node[i].id=i;}sort(node+1,node+n+1,cmp);for(int i=1;i<=n;++i) p[node[i].id]=i;S=p[1];T=p[n];h=max(node[S].z,node[T].z);for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j)d[i][j]=d[j][i]=get_dis(i,j);for(int i=1;i<=n;++i) fa[i]=i;int x,y;for(int i=1;i<=m;++i) {x=p[read()]; y=p[read()];d[x][y]=d[y][x]=0;add(x,y);}for(int i=1;i<=n;++i) {for(int j=fir[i];j;j=nxt[j])if(to[j]<i) fa[find(to[j])]=find(i);for(int j=1;j<=i;++j) if(!vis[j]) {//上面的联通可能会导致下面的有些点与S、T联通x=find(j);if(x==find(S)||x==find(T)) {now+=node[j].k; vis[j]=1;//j打成i}}if(node[i].z<h||(i!=n&&node[i].z==node[i+1].z)) continue;get_ans(i);}if(ans!=INF) printf("Case 1: %.4f",ans);else printf("Case 1: impossible");return 0;}
计算几何题
求能够构成的的个数,暴力代码:
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define db double#define ll long longconst int maxn=2333+10;const db eps=1e-11;int n;ll tot[3],ans;int aa,ff;char cc;int read() {aa=0;ff=1;cc=getchar();while(cc<'0'||cc>'9') {if(cc=='-') ff=-1;//忘记判断负数情况cc=getchar();}while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa*ff;}struct Node {db x,y;}node[maxn];db xx,yy,x2,y2;db X_(int i,int j,int k) {xx=node[j].x-node[i].x;x2=node[k].x-node[i].x;yy=node[j].y-node[i].y;y2=node[k].y-node[i].y;return xx*y2-yy*x2;}db D_(int i,int j,int k) {xx=node[j].x-node[i].x;x2=node[k].x-node[i].x;yy=node[j].y-node[i].y;y2=node[k].y-node[i].y;return xx*x2+yy*y2;}int main() {n=read();for(int i=1;i<=n;++i) node[i].x=read(),node[i].y=read();for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) {tot[1]=tot[2]=0;for(int k=1;k<=n;++k) if(k!=i&&k!=j) {if(X_(i,j,k)+eps<0&&D_(i,j,k)+eps>=0) ++tot[1];else if(X_(i,j,k)-eps>0&&D_(j,i,k)+eps>=0) ++tot[2];}ans+=tot[1]*tot[2];}printf("%lld",ans);return 0;}
cdq套cdq裸题
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;const int maxn=4e5+10;int T,n,tot,qtot,ans[maxn/6];int pz[maxn/4],tz;int aa;char cc;int read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}int ef(int x) {int l=1,r=tz,mid;while(l<=r) {mid=(l+r)>>1;if(pz[mid]==x) return mid;if(pz[mid]<x) l=mid+1;else r=mid-1;}}int xx[maxn],yy[maxn],zz[maxn],fnum[maxn];struct Ask{int qid,id;}ask[maxn],ask1[maxn],ask2[maxn];bool cmp(const Ask& a,const Ask& b) {return xx[a.id]==xx[b.id]? a.id < b.id : xx[a.id] < xx[b.id];//相同时必须比较id否则会挂}bool cmp2(const Ask& a,const Ask& b) {return yy[a.id]==yy[b.id]? a.id < b.id : yy[a.id] < yy[b.id];}void add(int x,int y,int z,int num) {fnum[++tot]=num;ask[tot].id=tot;xx[tot]=x;yy[tot]=y;zz[tot]=z;if(num) ask[tot].qid=qtot;}int sz[maxn];int q(int pos) {int rs=0;while(pos) {rs+=sz[pos];pos-=pos&-pos;}return rs;}void chge(int pos,int x) {while(pos<=tz) {sz[pos]+=x;pos+=pos&-pos;}}void cdq2(int l,int r) {if(l>=r) return;int mid=(l+r)>>1,now=0;cdq2(l,mid); cdq2(mid+1,r);for(int i=l;i<=mid;++i) if(!fnum[ask1[i].id]) ask2[++now]=ask1[i];for(int i=mid+1;i<=r;++i) if(fnum[ask1[i].id]) ask2[++now]=ask1[i];sort(ask2+1,ask2+now+1,cmp2);for(int i=1;i<=now;++i) {if(!fnum[ask2[i].id]) chge(zz[ask2[i].id],1);else ans[ask2[i].qid]+=fnum[ask2[i].id]*q(zz[ask2[i].id]);}for(int i=1;i<=now;++i) if(!fnum[ask2[i].id]) chge(zz[ask2[i].id],-1);}void cdq(int l,int r) {if(l>=r) return;int mid=(l+r)>>1,now=0;cdq(l,mid); cdq(mid+1,r);for(register int i=l;i<=mid;++i) if(!fnum[ask[i].id]) ask1[++now]=ask[i];for(register int i=mid+1;i<=r;++i) if(fnum[ask[i].id]) ask1[++now]=ask[i];sort(ask1+1,ask1+now+1,cmp);cdq2(1,now);}void clear() {memset(ans,0,sizeof(ans));tz=tot=qtot=0;}int main() {//提交的时候忘记关freopenT=read();int op,x,y,z,x1,y1,z1;while(T--) {n=read(); clear();for(int i=1;i<=n;++i) {op=read(); x=read(); y=read(); z=read();if(op==1) add(x,y,z,0),pz[++tz]=z;else {x1=read();y1=read();z1=read();++qtot; pz[++tz]=z1; pz[++tz]=z-1;add(x-1,y-1,z-1,-1); add(x1,y1,z1,1);add(x1,y-1,z-1,1); add(x-1,y1,z-1,1); add(x-1,y-1,z1,1);add(x-1,y1,z1,-1); add(x1,y-1,z1,-1); add(x1,y1,z-1,-1);//x、y、z需要-1}}sort(pz+1,pz+tz+1);//忘记sort了tz=unique(pz+1,pz+tz+1)-(pz+1);for(int i=1;i<=tot;++i) zz[i]=ef(zz[i]);//提前离散化跑得更快cdq(1,tot);for(int i=1;i<=qtot;++i) printf("%d\n",ans[i]);}return 0;}
一个裸的基环树+gcd
需要注意一些细节问题.
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longconst int maxn=1e5+10;int n,m,hst;ll d;ll aa;char cc;ll read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}int fir[maxn],nxt[2*maxn],to[2*maxn],e=1;ll v[2*maxn];void add(int x,int y,ll z) {to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=-z;}int zz[maxn],t,inh[maxn],vis[maxn];void dfs1(int pos,int p) {if(vis[pos]) {while(t&&zz[t]!=pos) inh[zz[t--]]=1;hst=pos; inh[pos]=1;return ;//忘了return直接段错误}vis[pos]=1; zz[++t]=pos;for(int y=fir[pos];y;y=nxt[y]) {if(y==p) continue;dfs1(to[y],y^1);}}ll dis[maxn],toth,fa[maxn];void dfs3(int pos,ll d,ll bel) {dis[pos]=d;fa[pos]=bel;vis[pos]=1;for(int y=fir[pos];y;y=nxt[y]) {if(vis[to[y]]) continue;dfs3(to[y],d+v[y],bel);}}void dfs2(int pos,ll d,int p) {dis[pos]=d;fa[pos]=pos;vis[pos]=1;for(int y=fir[pos];y;y=nxt[y]) {if(y==p) continue;if(!inh[to[y]]) dfs3(to[y],v[y],pos);else {if(vis[to[y]]) {if(to[y]==hst) toth=d+v[y];continue;}inh[to[y]]=inh[pos]+1;dfs2(to[y],d+v[y],y^1);}}}ll get_d(int x,int y) {if(x==y) return 0;if(inh[y]>inh[x]) return dis[y]-dis[x];return -toth+(dis[y]-dis[x]);//正负号弄反}ll gcd(ll x,ll y) {return y==0? x:gcd(y,x%y);}int main() {n=read(); ll x,y,z,now;for(int i=1;i<=n;++i) {x=read(); y=read(); z=read();add(x,y,z);}dfs1(1,0);memset(vis,0,sizeof(vis));dfs2(hst,0,0);m=read();for(int i=1;i<=m;++i) {x=read();y=read();z=read();d=0;if(fa[x]!=x) d-=dis[x];if(fa[y]!=y) d+=dis[y];d+=get_d(fa[x],fa[y]);d%=z; now=toth%z;if(d<=0) d+=z;if(now<=0) now+=z;now=gcd(now,z);d%=now;if(!d) d+=now;if((z-d)%now==0) printf("%lld\n",z-now);//必须特判否则挂else printf("%lld\n",((z-d)/now)*now+d);}return 0;}
Meet in the middle模板题
因为是无向图,所以可以把从i点到其他点可以得到的二进制数的问题转化为从其他点到i点可以得到的二进制数,所以对于第二个dp就很好处理了.
改题的时候T了一发
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longconst int maxn=97,maxm=2e4+7,maxt=(1<<10)|3;//maxm开小了,Tint n,m,d,totans,sz1,sz2;bool dp1[2][maxn][maxt],dp2[2][maxn][maxt];int aa;char cc;int read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}int fir[maxn],nxt[maxm],to[maxm],v[maxm],e=1;void add(int x,int y,int z) {to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=z;}bool vis[(1<<21)|5];int ans;void get_ans(int x) {if(!vis[x]) ++ans,vis[x]=1;}int main() {n=read(); m=read(); d=read();int x,y,z;for(int i=1;i<=m;++i) {x=read(); y=read(); z=read();add(x,y,z);}sz1=d/2; sz2=d-sz1;int p1=0,p2=0;dp1[0][1][0]=1;for(int s=1;s<=sz1;++s) {p1^=1;memset(dp1[p1],0,sizeof(dp1[p1]));for(int t=0;t<(1<<s-1);++t) for(int i=1;i<=n;++i) {if(dp1[p1^1][i][t]) for(int j=fir[i];j;j=nxt[j]) dp1[p1][to[j]][(t<<1)|v[j]]=1;}}for(int i=1;i<=n;++i) dp2[0][i][0]=1;for(int s=1;s<=sz2;++s) {p2^=1;memset(dp2[p2],0,sizeof(dp2[p2]));for(int t=0;t<(1<<s-1);++t) for(int i=1;i<=n;++i) {if(dp2[p2^1][i][t]) for(int j=fir[i];j;j=nxt[j]) dp2[p2][to[j]][(t<<1)|v[j]]=1;}}for(int i=1;i<=n;++i) for(int t=0;t<(1<<sz1);++t) if(dp1[p1][i][t]) {for(int tt=0;tt<(1<<sz2);++tt) if(dp2[p2][i][tt]) get_ans(t<<sz2|tt);}printf("%d\n",ans);return 0;}
一道sb题,但是场上sb了.
改题的时候发现题解所说的单调队列并不需要.
然后就自己随便搞了搞,跑得飞快(比std快3倍).
写了两个版本的代码,分别debug,特别难受,后来,,,
随便放一个跑得快的.
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longconst int maxn=2000+7;int n,m,k,up[maxn][maxn],down[maxn][maxn],ans,nowans[maxn][maxn],p[maxn];bool ok[maxn][maxn];ll aa;char cc;ll read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}struct Ask{int x,y;}ask[maxn];int f[maxn][maxn],g[maxn][maxn];bool check(int x,int y,int t) {if(t>m||t>n) return 0;int l=y,r=y,pos1,pos2,now1,now2;f[x][y]=up[x][y];g[x][y]=down[x][y];//一开始g也用的up赋值now1=up[x][y]; now2=down[x][y];while(now1+now2-1>=t&&l) {l--;now1=min(now1,up[x][l]);now2=min(now2,down[x][l]);f[x][l]=now1;g[x][l]=now2;}l++;now1=up[x][y]; now2=down[x][y];while(now1+now2-1>=t&&r<=m) {r++;now1=min(now1,up[x][r]);now2=min(now2,down[x][r]);f[x][r]=now1;g[x][r]=now2;}r--;if(r-l+1<t) return 0;pos1=l;for(pos2=y;pos2<=r&&f[x][pos2]+g[x][pos2]-1>=t;++pos2) {while(min(f[x][pos1],f[x][pos2])+min(g[x][pos1],g[x][pos2])-1<t) pos1++;if(pos2-pos1+1>=t) return 1;}pos2=r;for(pos1=y;pos1>=l&&f[x][pos1]+g[x][pos1]-1>=t;--pos1) {while(min(f[x][pos1],f[x][pos2])+min(g[x][pos1],g[x][pos2])-1<t) pos2--;if(pos2-pos1+1>=t) return 1;}return 0;}int main() {n=read(); m=read(); k=read();for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) {do cc=getchar();while(cc!='X'&&cc!='.');if(cc=='X') ok[i][j]=1;}for(int i=1;i<=k;++i) {ask[i].x=read(); ask[i].y=read();ok[ask[i].x][ask[i].y]=1;}for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) up[i][j]= ok[i][j]? 0 : up[i-1][j]+1;for(int i=n;i;--i) for(int j=1;j<=m;++j) down[i][j]= ok[i][j]? 0 : down[i+1][j]+1;for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) {if(ok[i][j]) nowans[i][j]=0;else nowans[i][j]=min(nowans[i-1][j-1],min(nowans[i-1][j],nowans[i][j-1]))+1;ans=max(ans,nowans[i][j]);}p[k]=ans;int x,y,l,r,len1,len2;for(int qaq=k;qaq>1;--qaq) {x=ask[qaq].x;y=ask[qaq].y;ok[x][y]=0;for(int i=x;i<=n&&!ok[i][y];++i) up[i][y]=up[i-1][y]+1;for(int i=x;i&&!ok[i][y];--i) down[i][y]=down[i+1][y]+1;//曾把x和y弄错while(check(x,y,ans+1)) ++ans;p[qaq-1]=ans;}for(int i=1;i<=k;++i) printf("%d\n",p[i]);return 0;}
一道网络流解决可行流的问题,场上连了负边特别难受.
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longconst ll maxn=200+10,maxm=1000+10,INF=1e9;//数组开小了ll n,m,S,T,ind[maxn];ll ans;ll aa;char cc;ll read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}struct Node{int x,y;ll cap,flow,w;Node(){}Node(int x,int y,ll cap,ll w):x(x),y(y),cap(cap),w(w){flow=0;}}node[2*maxm];int fir[maxn],nxt[2*maxm],e=1;void add(int x,int y,ll z,ll w) {node[++e]=Node(x,y,z,w); nxt[e]=fir[x]; fir[x]=e;node[++e]=Node(y,x,0,-w); nxt[e]=fir[y];fir[y]=e;}ll zz[maxn],dis[maxn],from[maxn];bool vis[maxn];bool spfa() {for(int i=1;i<=n+2;++i) dis[i]=INF,from[i]=0;//写成了i<=nint s=1,t=0,x,y,z,o;dis[S]=0; zz[++t]=S;vis[S]=1;while(s<=t) {x=zz[s%maxn];s++; vis[x]=0;for(y=fir[x];y;y=nxt[y]) {z=node[y].y;if(node[y].flow>=node[y].cap||dis[z]<=dis[x]+node[y].w) continue;dis[z]=dis[x]+node[y].w;from[z]=y;if(!vis[z]) {vis[z]=1; t++;zz[t%maxn]=z;}}}return dis[T]<INF;//一开始建负边的时候写的<0后来忘了改回来}ll MCMF() {ll rs=0,now;while(spfa()) {now=INF;for(int x=T;x!=S;x=node[from[x]].x) now=min(now,node[from[x]].cap-node[from[x]].flow);for(int x=T;x!=S;x=node[from[x]].x) {rs+=now*node[from[x]].w;node[from[x]].flow+=now;node[from[x]^1].flow-=now;}}return rs;}int main() {n=read(); m=read();int x,y,f,c; S=n+1;T=n+2;for(int i=1;i<=m;++i) {x=read(); y=read(); c=read(); f=read();ind[y]+=f; ind[x]-=f;if(f<=c) {add(y,x,f,1);if(f!=c) add(x,y,c-f,1);add(x,y,INF,2);}else {ans+=f-c;add(y,x,f-c,0);add(y,x,c,1);add(x,y,INF,2);}}for(int i=1;i<=n;++i) {if(ind[i]<0) add(i,T,-ind[i],0);else if(ind[i]>0) add(S,i,ind[i],0);}add(n,1,INF,0);ans+=MCMF();printf("%lld",ans);return 0;}
逐渐明白样例是多么水的东西,对拍是多么优秀的东西
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longconst int maxn=2e5+10;int n,p1[maxn],p2[maxn],t1,t2;ll ans;int aa;char cc;int read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}int now[maxn];struct Node{int x,y,id;}node[maxn];bool cmp(const Node& a,const Node& b) {return a.x < b.x;}bool cmp2(const Node& a,const Node& b) {return now[a.y] < now[b.y];}int ef(int x,int *p,int r) {int l=1,mid;while(l<=r) {mid=(l+r)>>1;if(p[mid]==x) return mid;if(p[mid]<x) l=mid+1;else r=mid-1;}}int zz[2][maxn];int ef2(int x) {int l=0,r=t1,mid;if(node[zz[0][r]].x<x) return r+1;//一开始写特判t1=0的情况写错了while(l<r-1) {mid=(l+r)>>1;if(node[zz[0][mid]].x>x) r=mid;//栈里面放的是标号而不是直接的xelse l=mid;}return r;}void add(int p,int x) {if(!p) {while(t1&&node[zz[0][t1]].y<=node[x].y) --t1;//栈里面放标号,按照y递减zz[0][++t1]=x;}else {while(t2&&node[zz[1][t2]].y>=node[x].y) --t2;zz[1][++t2]=x;//++写成--了if(t2>1) ans+=(ll)t1-(ll)ef2(node[zz[1][t2-1]].x)+1;else ans+=t1;}}void cdq(int l,int r) {if(l==r) return; t1=0; t2=0;int mid=(l+r)>>1,pos1=l,pos2=mid+1;for(int i=l;i<=r;++i) {if(node[i].y<=mid) add(0,i),now[node[i].y]=++pos1;else add(1,i),now[node[i].y]=++pos2;}sort(node+l,node+r+1,cmp2);cdq(l,mid); cdq(mid+1,r);}int main() {freopen("scarecrows.in","r",stdin);freopen("scarecrows.out","w",stdout);n=read();for(int i=1;i<=n;++i) {p1[++t1]=node[i].x=read();p2[++t2]=node[i].y=read();}sort(p1+1,p1+t1+1);sort(p2+1,p2+t2+1);for(int i=1;i<=n;++i) {node[i].x=ef(node[i].x,p1,t1);node[i].y=ef(node[i].y,p2,t2);}sort(node+1,node+n+1,cmp);cdq(1,n);printf("%lld",ans);return 0;}
一道数学题
没什么好说的就是忘了取模,做题的时候一定要注意数据范围
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longll T,p,n,m;ll f[3],g[3][3],f2[3],g2[3][3];ll aa;char cc;ll read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}ll gcd(ll x,ll y) {return y==0? x:gcd(y,x%y);}void cf1() {memcpy(f2,f,sizeof(f));f[1]=f2[1]*g[1][1]%p+f2[2]*g[2][1]%p;f[2]=f2[1]*g[1][2]%p+f2[2]*g[2][2]%p;if(f[1]>=p) f[1]-=p;if(f[2]>=p) f[2]-=p;}void cf2() {memcpy(g2,g,sizeof(g));memset(g,0,sizeof(g));for(int i=1;i<=2;++i) for(int j=1;j<=2;++j) for(int k=1;k<=2;++k) {g[i][j]+=g2[i][k]*g2[k][j]%p;if(g[i][j]>=p) g[i][j]-=p;}}void qpz(ll k) {f[1]=f[2]=1; g[1][1]=0;g[1][2]=g[2][1]=g[2][2]=1;while(k) {if(k&1) cf1();cf2(); k>>=1;}}ll qp(ll x,ll k) {ll rs=1;while(k) {if(k&1) rs=rs*x%p;k>>=1; x=x*x%p;}return rs;}void exgcd(ll a,ll b,ll &x,ll &y) {if(!b) {x=1; y=0;return;}exgcd(b,a%b,y,x);y-=(a/b)*x;}ll get_ans(ll r,ll x,ll b) {if(r<0) return 0;ll rs=r/b;if(r%b>=x) rs++;return rs;}int main() {freopen("1.in","r",stdin);freopen("test.out","w",stdout);T=read();ll x,y,a,b,c,o,l,r,w;while(T--) {w=read(); l=read(); r=read();n=read(); p=read(); m=read();qpz(n-3);a=f[2]; b=p; c=(m%p-w%p*f[1]%p+p)%p;//if(c%(o=gcd(a,b))) {printf("0\n"); continue;}a/=o; b/=o; c/=o;exgcd(a,b,x,y); x*=c;x%=b; if(x<0) x+=b;printf("%lld\n",get_ans(r,x,b)-get_ans(l-1,x,b));}fclose(stdin);fclose(stdout);return 0;}/*1692858490132927148 33 93 11 90 52*/
网络流题,给一些前缀和后缀,每个前缀或后缀都有一个代价,你需要用最小的代价覆盖所有的数字。
先对前缀和后缀各建一个字典树,然后直接在字典树上建图跑最大流(最小割)。
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;const int maxn=800+7,maxm=maxn*maxn,INF=0x3f3f3f3f;//int n,m,a[maxn],len,S,T;bool ok[maxn];char c[23],s[23];int aa;char cc;int read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}//////////////////////////////////////////////////////////////Dinicstruct Node{int x,y,flow,cap;Node(){}Node(int x,int y,int cap):x(x),y(y),cap(cap){flow=0;}}node[2*maxm];int cur[maxn],fir[maxn],nxt[2*maxm],e=1;int ind[maxn];void add(int x,int y,int z) {// printf("add: %d -> %d cap:%d\n",x,y,z);node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;}int dis[maxn],zz[maxn];bool BFS() {memset(dis,-1,sizeof(dis));int x,y,z,s=1,t=0;zz[++t]=S; dis[S]=1;while(s<=t) {x=zz[s++];for(y=fir[x];y;y=nxt[y]) {if(dis[z=node[y].y]!=-1||node[y].flow>=node[y].cap) continue;dis[z]=dis[x]+1;zz[++t]=z;}}return dis[T]!=-1;}int DFS(int pos,int maxf) {if(pos==T||!maxf) return maxf;int z,now,rs=0;for(int &y=cur[pos];y&&maxf;y=nxt[y]) {if(dis[z=node[y].y]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;now=DFS(z,min(maxf,node[y].cap-node[y].flow));node[y].flow+=now;node[y^1].flow-=now;rs+=now; maxf-=now;}if(!rs) dis[pos]=-1;return rs;}int Dinic() {int rs=0;while(BFS()) {memcpy(cur,fir,sizeof(fir));rs+=DFS(S,INF);}return rs;}////////////////////////////////////////////////////////////////bool check(int r,int x,int p,int len) {if(p==0) return (r>>(8-len))==x;else {r&=((1<<len)-1);return r==x;}}int le[maxn],num[maxn],cost[maxn];int t[2]={1,1};struct G{int num,son[2];}g[2][maxn*4];void insert(int p,int x,int len,int i) {int now=1,r;if(!p) {int xx=x; x=0;for(int i=1;i<=len;++i,xx>>=1) {x<<=1;x+=(xx&1);}}while(len--) {r=x&1; x>>=1;if(!g[p][now].son[r]) g[p][now].son[r]=++t[p];now=g[p][now].son[r];}if(!g[p][now].num) g[p][now].num=i;else if(cost[g[p][now].num] > cost[i]) g[p][now].num=i;}void dfs1(int pos,int f) {if(!pos) return;int id=g[0][pos].num;if(id) add(f,n+id,cost[id]),f=id+n;//dfs1(g[0][pos].son[0],f);dfs1(g[0][pos].son[1],f);if(id) {for(int j=1;j<=n;++j) if((!ok[j])&&check(a[j],num[id],0,le[id])) {ok[j]=1; add(n+id,j,INF);}}}void dfs2(int pos,int f) {if(!pos) return;int id=g[1][pos].num;if(id) add(n+id,f,cost[id]),f=id+n;dfs2(g[1][pos].son[0],f);dfs2(g[1][pos].son[1],f);if(id) {for(int j=1;j<=n;++j) if((!ok[j])&&check(a[j],num[id],1,le[id])) {ok[j]=1; add(j,n+id,INF);}}}int main() {freopen("C.in","r",stdin);freopen("C.out","w",stdout);n=read(); m=read(); int x,p;S=n+m+1; T=S+1;memset(g,0,sizeof(g));for(int i=1;i<=n;++i) a[i]=read();for(int i=1;i<=m;++i) {scanf("%s%s",c+1,s+1);cost[i]=read();le[i]=len=strlen(s+1);x=0; p= c[1]=='S';//0前缀 1后缀for(int j=1;j<=len;++j) {x<<=1;x+=(s[j]-'0');}num[i]=x;for(int j=1;j<=n;++j) if(check(a[j],x,p,len)) ok[j]=1;insert(p,x,len,i);}for(int i=2;i<=n;++i) ok[1]&=ok[i];if(!ok[1]) printf("-1");else {memset(ok,0,sizeof(ok));dfs1(1,S);for(int i=1;i<=n;++i) if(!ok[i]) add(S,i,INF);//一开始没有考虑到memset(ok,0,sizeof(ok));dfs2(1,T);for(int i=1;i<=n;++i) if(!ok[i]) add(i,T,INF);printf("%d\n",Dinic());}fclose(stdin); fclose(stdout);return 0;}/*8 70 1 2 3 4 5 6 6P 000001 3P 0000000 2P 0000010 1P 0000000 1S 10 1S 11 1S 00 1S 01 1*/
一个模意义下开根的模板题。第一次写,还是debug了一个小时。
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longll T,n,p,ans;ll f[3],g[3][3],f2[3],g2[3][3];ll aa;char cc;ll read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}void cf1() {memcpy(f2,f,sizeof(f));f[1]=f2[1]*g[1][1]%p+f2[2]*g[2][1]%p;f[2]=f2[1]*g[1][2]%p+f2[2]*g[2][2]%p;if(f[1]>=p) f[1]-=p;if(f[2]>=p) f[2]-=p;}void cf2() {memcpy(g2,g,sizeof(g));memset(g,0,sizeof(g));for(int i=1;i<=2;++i) for(int j=1;j<=2;++j) for(int k=1;k<=2;++k) {g[i][j]+=g2[i][k]*g2[k][j]%p;if(g[i][j]>=p) g[i][j]-=p;}}void qpz(ll k) {f[1]=f[2]=1; g[1][1]=0;g[1][2]=g[2][1]=g[2][2]=1;while(k) {if(k&1) cf1();cf2(); k>>=1;}}ll qp(ll x,ll k) {ll rs=1;while(k) {if(k&1) rs=rs*x%p;k>>=1; x=x*x%p;}return rs;}bool check(ll x) {x%=p;return qp(x,(p-1)>>1) == 1;}ll get_sq(ll x) {ll a,wpf; x%=p;do a=rand()%(2*p);while(!a||check(a*a-x));wpf=(a*a-x)%p;ll rs1=1,rs2=0,x1=a,x2=1,k=(p+1)>>1,aa,bb;//一开始x1写成了1while(k) {if(k&1) {aa=(rs1*x1%p+rs2*x2%p*wpf%p)%p;bb=(rs1*x2%p+rs2*x1%p)%p;rs1=aa; rs2=bb;}k>>=1;aa=(x1*x1%p+x2*x2%p*wpf%p)%p;bb=2*x1*x2%p;x1=aa; x2=bb;}return rs1;}int main() {srand(1031); ll a,b;T=read();while(T--) {a=read(); b=read(); n=read(); p=read();if((!check(a)||(!check(b)))) printf("0\n");else {a=get_sq(a);b=get_sq(b);p--; qpz(n-1);f[1]=f[1]*2%p; f[2]=f[2]*2%p;p++; ans=(qp((a+b+p)%p,f[2])+qp((a-b+p)%p,f[2]))%p;printf("%lld\n",ans*4%p);}}return 0;}/*42 3 1 100072 3 2 100072 3 3 100072 3 4 10007*/
和去年省选D2T3很像,但不用本质不同,而且简单很多,用后缀数组和马拉车预处理lcp和以i为开头的回文串(放到树状数组里)bug弄了一晚上
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;#define ll long longconst int maxn=16e5+10,INF=0x3f3f3f3f;int n,m,Q,ql,qr;ll totans;char A[maxn],B[maxn],S[2*maxn];int x[maxn],y[maxn],c[maxn],sa[maxn],h[maxn],rad[maxn];ll aa;char cc;ll read() {aa=0;cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();return aa;}ll minnum[4*maxn];void bld(int pos,int l,int r) {if(l==r) {minnum[pos]=h[l];return;}int mid=(l+r)>>1;bld(pos<<1,l,mid); bld(pos<<1|1,mid+1,r);minnum[pos]=min(minnum[pos<<1],minnum[pos<<1|1]);}ll qmin(int pos,int l,int r) {if(l>=ql&&r<=qr) return minnum[pos];int mid=(l+r)>>1;ll rs=INF;if(ql<=mid) rs=min(rs,qmin(pos<<1,l,mid));if(qr>mid) rs=min(rs,qmin(pos<<1|1,mid+1,r));return rs;}ll tot[2][maxn],sum[2][maxn];ll q(int pos,ll *sz) {ll rs=0;while(pos) {rs+=sz[pos];pos-=pos&-pos;}return rs;}void chge(int pos,int x,ll *sz,int n) {while(pos<=n) {sz[pos]+=x;pos+=pos&-pos;}}void get_sa(char *s,int n) {int m='z'+1,p;for(int i=0;i<n;++i) c[x[i]=s[i]]++;for(int i=1;i<m;++i) c[i]+=c[i-1];for(int i=n-1;i>=0;--i) sa[--c[x[i]]]=i;for(int k=1;k<=n;k<<=1) {p=0;for(int i=n-1;i>=n-k;--i) y[p++]=i;for(int i=0;i<n;++i) if(sa[i]>=k) y[p++]=sa[i]-k;for(int i=0;i<m;++i) c[i]=0;for(int i=0;i<n;++i) c[x[y[i]]]++;for(int i=1;i<m;++i) c[i]+=c[i-1];for(int i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i];swap(x,y);p=1;x[sa[0]]=0;for(int i=1;i<n;++i)x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&((sa[i]+k<n&&sa[i-1]+k<n&&y[sa[i]+k]==y[sa[i-1]+k])||(sa[i]+k>=n&&sa[i-1]+k>=n))? p-1:p++;if(p>=n) break; else m=p;}p=0;int u;for(int i=0;i<n;++i) {if(!x[i]) continue;u=sa[x[i]-1];if(p) p--;while(s[u+p]==s[i+p]) p++;h[x[i]]=p;}memset(minnum,0x3f3f3f3f,sizeof(minnum));bld(1,1,n-1);}void manacher(char *s,ll *sz,int len,int o) {int maxpos=0,p=0;for(int i=len;i;--i) {//不是从0开始而是从1开始s[i<<1]=s[i];s[i<<1|1]='#';}s[0]=s[1]='#';for(int i=2;i<=2*len;++i) {if(maxpos>i) rad[i]=min(maxpos-i,rad[2*p-i]);else rad[i]=0;while(i-rad[i]>0&&i+rad[i]<=2*len+1&&s[i-rad[i]]==s[i+rad[i]]) rad[i]++;rad[i]--;if(i+rad[i]>maxpos) p=i,maxpos=i+rad[i];}for(int i=2;i<=2*len;++i) {chge((i-rad[i]+1)>>1,1,tot[o],len);chge((i+2)>>1,-1,tot[o],len);}}int main() {freopen("palindrome.in","r",stdin);freopen("palindrome.out","w",stdout);scanf("%s",A+1);scanf("%s%s",A+1,B+1);n=strlen(A+1); m=strlen(B+1);for(int i=1;i<=m/2;++i) swap(B[i],B[m-i+1]);for(int i=1;i<=n;++i) S[i-1]=A[i]; S[n]='#';//n不是n+1for(int i=1;i<=m;++i) S[i+n]=B[i];get_sa(S,n+m+1);manacher(A,tot[0],n,0);manacher(B,tot[1],m,1);for(int i=1;i<=n;++i) chge(i,q(i,tot[0]),sum[0],n+1);for(int i=1;i<=m;++i) chge(i,q(i,tot[1]),sum[1],m+1);//注意是n+1和m+1,因为可能询问到Q=read();int xx,yy,len;for(int i=1;i<=Q;++i) {xx=read(); yy=read();ql=x[xx-1]; qr=x[yy+n];if(qr<ql) swap(ql,qr);++ql;len=qmin(1,1,n+m);totans=len;totans+=q(xx+len,sum[0])-q(xx,sum[0]);totans+=q(yy+len,sum[1])-q(yy,sum[1]);//注意边界printf("%lld\n",totans);}fclose(stdin);fclose(stdout);return 0;}/*orzAchenbabaabbbabaaabbb19 6*/