[关闭]
@shixinyi 2018-01-04T12:46:34.000000Z 字数 30368 阅读 637

每日bug

OI


2017.12

03 test 1203 T1 数字

相当于%9,但是余0的是9。

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. ll T,l,r;
  11. ll aa;char cc;
  12. ll read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. ll cnt[20];
  19. ll get_ans(ll x) {
  20. if(x<=0) return x+1;
  21. ll rs=1;//0
  22. for(ll i=1;i<=9;++i) rs+=(cnt[i]=(x-i*i+i*9)/(i*9));//用循环简单一些
  23. rs-=cnt[1]/8;
  24. rs-=cnt[2]/7;
  25. rs-=cnt[3]/2;
  26. rs-=cnt[4]/5;
  27. return rs;
  28. }
  29. int main() {
  30. T=read();
  31. while(T--) {
  32. l=read();r=read();
  33. printf("%lld\n",get_ans(r)-get_ans(l-1));
  34. }
  35. return 0;
  36. }

03 test 1203 T2 探险

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=1e4+10,maxm=4e5+10,INF=0x3f3f3f3f;//maxm开小了
  10. int n,m,ans=INF;
  11. int aa;char cc;
  12. int read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. int fir[maxn],nxt[maxm],to[maxm],v[maxm],e=0;
  19. void add(int x,int y,int z) {
  20. to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;
  21. }
  22. int dis[maxn],zz[maxn];
  23. bool vis[maxn];
  24. int spfa(int st) {
  25. int s=1,t=0,x,y,z,tot=1;
  26. memset(dis,0x3f3f3f3f,sizeof(dis));
  27. dis[st]=0;vis[st]=1;zz[++t]=st;
  28. while(tot--) {
  29. x=zz[s];s=(s+1)%maxn;vis[x]=0;
  30. for(y=fir[x];y;y=nxt[y]) {
  31. if(dis[z=to[y]]<=dis[x]+v[y]||(x==st&&z==1)) continue;
  32. dis[z]=dis[x]+v[y];
  33. if(!vis[z]) {
  34. vis[z]=1;tot++;
  35. if(dis[z]<=dis[zz[s]]) {
  36. s=(s-1+maxn)%maxn;
  37. zz[s]=z;
  38. }
  39. else {
  40. t=(t+1)%maxn;
  41. zz[t]=z;
  42. }
  43. }
  44. }
  45. }
  46. return dis[1];
  47. }
  48. int main() {
  49. n=read(); m=read();
  50. int x,y,z1,z2;
  51. for(int i=1;i<=m;++i) {
  52. x=read();y=read();
  53. z1=read();z2=read();
  54. if(x>y) swap(x,y),swap(z1,z2);
  55. add(x,y,z1); add(y,x,z2);
  56. }
  57. for(y=fir[1];y;y=nxt[y]) ans=min(ans,spfa(to[y])+v[y]);
  58. printf("%d",ans);
  59. return 0;
  60. }

05 test 1205 T1 safe

正向跑一次,反向跑一次,求交点。

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. #include<set>
  9. using namespace std;
  10. #define ll long long
  11. const int maxn=8e5+10,INF=1e7;
  12. int n,m,cse,tot1,tot2,p[maxn],tt,S,T,ok;
  13. bool vis[2*maxn];
  14. int aa;char cc;
  15. int read() {
  16. aa=0;cc=getchar();
  17. while(cc<'0'||cc>'9') cc=getchar();
  18. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  19. return aa;
  20. }
  21. struct Node{
  22. int x,y,p;
  23. }node[2*maxn];
  24. bool cmp1(int a,int b) {
  25. return node[a].x==node[b].x? node[a].y<node[b].y : node[a].x<node[b].x;
  26. }
  27. bool cmp2(int a,int b) {
  28. return node[a].y==node[b].y? node[a].x<node[b].x : node[a].y<node[b].y;
  29. }
  30. int fir[4*maxn],nxt[4*maxn],to[4*maxn],e;
  31. void add(int x,int y) {
  32. // printf("add: %d %d\n",x,y);
  33. to[++e]=y;nxt[e]=fir[x];fir[x]=e;
  34. to[++e]=x;nxt[e]=fir[y];fir[y]=e;
  35. }
  36. void init() {
  37. tot1=read();tot2=read();tt=tot1+tot2;
  38. S=tt*2+1;T=S+1;
  39. for(int i=1;i<=tot1;++i) {
  40. node[i].x=read();
  41. node[i].y=read();
  42. node[i].p=0;
  43. }
  44. for(int i=1;i<=tot2;++i) {
  45. node[i+tot1].x=read();
  46. node[i+tot1].y=read();
  47. node[i+tot1].p=1;
  48. }
  49. node[S].x=1;node[S].y=0;
  50. node[T].x=n;node[T].y=m+1;
  51. }
  52. void get_edge() {
  53. for(int i=1;i<=tt;++i) p[i]=i;
  54. sort(p+1,p+tt+1,cmp1);
  55. for(int i=2;i<=tt;++i) if(node[p[i-1]].x==node[p[i]].x) add(p[i-1]+tt,p[i]);
  56. if(node[p[1]].x==1) add(S,p[1]);
  57. if(node[p[tt]].x==n) add(p[tt]+tt,T);
  58. for(int i=1;i<=tt;++i) p[i]=i;
  59. sort(p+1,p+tt+1,cmp2);
  60. for(int i=2;i<=tt;++i) if(node[p[i-1]].y==node[p[i]].y)
  61. add(p[i-1]+tt*(int)(node[p[i-1]].p==0),p[i]+tt*(int)(node[p[i]].p==1));
  62. }
  63. int get_d(int tox,int x) {
  64. if(!x) return (tox+1)%4+1;
  65. return 5-tox;
  66. }
  67. struct Line{
  68. int x,y,z;
  69. }li[5][2*maxn];
  70. int tot[5];
  71. //0~3
  72. bool cmp3(const Line& a,const Line& b) {
  73. return a.z==b.z? a.x<b.x:a.z<b.z;//写反了
  74. }
  75. void bld1(int x,int y,int p) {
  76. p=(p-1)<<1;
  77. if(x<S&&x>tt) x-=tt;
  78. int ff=(node[x].y==node[y].y);
  79. int s=(++tot[p+=ff]);
  80. if(!ff) li[p][s].x=node[x].y,li[p][s].y=node[y].y,li[p][s].z=node[x].x;
  81. else li[p][s].x=node[x].x,li[p][s].y=node[y].x,li[p][s].z=node[x].y;
  82. }
  83. void bld2(int x,int tox,int p) {
  84. p=(p-1)<<1;
  85. if(x<S&&x>tt) x-=tt;
  86. int ff=tox/3;
  87. int s=(++tot[p+=ff]);
  88. if(!ff) li[p][s].z=node[x].x;
  89. else li[p][s].z=node[x].y;
  90. if(tox==1) li[p][s].x=node[x].y,li[p][s].y=m+1;
  91. else if(tox==2) li[p][s].y=node[x].y,li[p][s].x=0;
  92. else if(tox==3) li[p][s].y=node[x].x,li[p][s].x=0;
  93. else li[p][s].x=node[x].x,li[p][s].y=n+1;
  94. }
  95. bool dfs(int pos,int tox,int p) {
  96. vis[pos]=1;
  97. int y,z,g,d,ok=0;
  98. for(y=fir[pos];y;y=nxt[y]) {
  99. if(vis[z=to[y]]) continue;
  100. if((z==T&&p==1)||(z==S&&p==2)) return 1;
  101. else if(z==T||z==S) {
  102. ok=0; break;
  103. }
  104. ok=1; g=(z-1)%tt+1;d=get_d(tox,node[g].p);
  105. bld1(pos,g,p);
  106. if(dfs(z,d,p)) return 1;
  107. }
  108. vis[pos]=0;
  109. if(!ok) bld2(pos,tox,p);
  110. return 0;
  111. }
  112. set<ll> Gpl[2],Gmi[2];
  113. set<ll>::iterator it1,it2;
  114. int sz[3*maxn];
  115. int q(int pos) {
  116. int rs=0;
  117. while(pos) {
  118. rs+=sz[pos];
  119. pos-=(pos&-pos);
  120. }
  121. return rs;
  122. }
  123. void chge(int pos,int x) {
  124. while(pos<=m) {
  125. sz[pos]+=x;
  126. pos+=(pos&-pos);
  127. }
  128. }
  129. int ans,ansx,ansy;
  130. void rn(int x,int l,int r) {
  131. int lx=l-1,rx=r,t=q(l-1),mid;
  132. while(lx<rx-1) {
  133. mid=(lx+rx)>>1;
  134. if(q(mid)>t) rx=mid;
  135. else lx=mid;
  136. }
  137. if(x<ansx||(x==ansx&&rx<ansy)) {
  138. ansx=x;ansy=rx;
  139. }
  140. ok=1;
  141. }
  142. void get_ans() {
  143. for(int i=0;i<4;++i) {
  144. for(int j=1;j<=tot[i];++j) {
  145. if(li[i][j].x>li[i][j].y) swap(li[i][j].x,li[i][j].y);
  146. ++li[i][j].x;--li[i][j].y;
  147. if(li[i][j].x>li[i][j].y) li[i][j].z=INF;//z写的x
  148. }
  149. }
  150. ans=0;
  151. sort(li[0]+1,li[0]+tot[0]+1,cmp3);
  152. sort(li[2]+1,li[2]+tot[2]+1,cmp3);
  153. while(tot[0]&&li[0][tot[0]].z==INF) tot[0]--;
  154. while(tot[2]&&li[2][tot[2]].z==INF) tot[2]--;
  155. Gpl[0].clear();Gmi[0].clear();
  156. Gpl[1].clear();Gmi[1].clear();//忘记clear
  157. for(int i=1;i<4;i+=2) {
  158. for(int j=1;j<=tot[i];++j) {
  159. if(li[i][j].z==INF) continue;
  160. Gpl[i>2].insert((ll)li[i][j].z+(ll)li[i][j].x*INF);
  161. Gmi[i>2].insert((ll)li[i][j].z+(ll)(li[i][j].y+1)*INF);//应该以x或y为第一关键字
  162. }
  163. }
  164. memset(sz,0,sizeof(sz));
  165. int pos=1;it1=Gpl[1].begin();it2=Gmi[1].begin();
  166. int l,r,now;ok=0;
  167. for(int i=1;i<=n&&pos<=tot[0];++i) {
  168. while(it1!=Gpl[1].end()&&(*it1)/(ll)INF==i) chge((*it1)%(ll)INF,1),it1++;
  169. while(it2!=Gmi[1].end()&&(*it2)/(ll)INF==i) chge((*it2)%(ll)INF,-1),it2++;//ll
  170. l=0;r=0;
  171. while(pos<=tot[0]&&li[0][pos].z==i) {
  172. l=max(l,li[0][pos].x);r=max(l-1,li[0][pos].y);
  173. if(l<=r) {
  174. ans+=(now=q(r)-q(l-1));
  175. if(!ok&&now) rn(i,l,r);
  176. }
  177. l=r+1; pos++;
  178. }
  179. }
  180. memset(sz,0,sizeof(sz));
  181. pos=1;it1=Gpl[0].begin();it2=Gmi[0].begin(); ok=0;
  182. for(int i=1;i<=n&&pos<=tot[2];++i) {
  183. while(it1!=Gpl[0].end()&&(*it1)/(ll)INF==i) chge((*it1)%(ll)INF,1),it1++;
  184. while(it2!=Gmi[0].end()&&(*it2)/(ll)INF==i) chge((*it2)%(ll)INF,-1),it2++;
  185. l=0;r=0;
  186. while(pos<=tot[2]&&li[2][pos].z==i) {
  187. l=max(l,li[2][pos].x);r=max(l-1,li[2][pos].y);
  188. if(l<=r) {
  189. ans+=(now=q(r)-q(l-1));
  190. if(!ok&&now) rn(i,l,r);
  191. }
  192. l=r+1; pos++;
  193. }
  194. }
  195. }
  196. void clear() {
  197. memset(fir,0,sizeof(fir));
  198. memset(nxt,0,sizeof(nxt));
  199. memset(vis,0,sizeof(vis));
  200. e=0;ansx=n+1;ansy=m+1;
  201. tot[0]=tot[1]=tot[2]=tot[3]=0;
  202. }
  203. int main() {
  204. while(scanf("%d%d",&n,&m)==2) {
  205. printf("Case %d: ",++cse);
  206. clear(); init();
  207. get_edge();
  208. if(dfs(S,1,1)||dfs(T,2,2)||(n==1&&!tot1&&!tot2)) printf("0");//n==1的情况直接射出去
  209. else if(n==1) printf("impossible");
  210. else {
  211. get_ans();
  212. if(ans) printf("%d %d %d",ans,ansx,ansy);
  213. else printf("impossible");
  214. }
  215. printf("\n");
  216. }
  217. return 0;
  218. }

06 test 1206 T2 minflow

直接枚举z,然后用并查集维护联通快,跑最短路。
因为中间有一些已经连好的边,所以不能直接只判断从S所在联通块直接到T所在联通块的最短距离

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. #include<queue>
  9. using namespace std;
  10. #define ll long long
  11. #define db double
  12. const int maxn=400+10,maxm=5e4+10;
  13. const db INF=1e17;
  14. ll n,m,S,T,p[maxn],fa[maxn],h,now;
  15. db d[maxn][maxn],ans=INF;
  16. bool vis[maxn];
  17. ll aa,ff;char cc;
  18. ll read() {
  19. aa=0;cc=getchar();ff=1;
  20. while(cc<'0'||cc>'9') {
  21. if(cc=='-') ff=-1;
  22. cc=getchar();
  23. }
  24. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  25. return aa*ff;
  26. }
  27. struct Node{
  28. ll x,y,z,k;int id;
  29. }node[maxn];
  30. bool cmp(const Node& a,const Node& b) {
  31. return a.z < b.z;
  32. }
  33. db pf(db x) {return x*x;}
  34. db get_dis(int a,int b) {
  35. return sqrt(pf(node[a].x-node[b].x)+pf(node[a].y-node[b].y)+pf(node[a].z-node[b].z));
  36. }
  37. int fir[maxn],nxt[2*maxm],to[2*maxm],e=0;
  38. void add(int x,int y) {
  39. to[++e]=y;nxt[e]=fir[x];fir[x]=e;
  40. to[++e]=x;nxt[e]=fir[y];fir[y]=e;
  41. }
  42. int find(int x) {
  43. return fa[x]==x? x:fa[x]=find(fa[x]);
  44. }
  45. struct Di{
  46. int x,p;db d;
  47. Di(){}
  48. Di(int x,int p,db d):x(x),p(p),d(d){}
  49. bool operator <(const Di& b) const{
  50. return d > b.d;
  51. }
  52. };
  53. priority_queue<Di> G;
  54. db dis[maxn][2];
  55. void get_ans(int pos) {
  56. for(int i=1;i<=n;++i) dis[i][0]=dis[i][1]=INF;
  57. dis[S][0]=0; G.push(Di(S,0,0));
  58. int x,y,t; db rs=(db)now*0.5,ad,dx;//dx开成int
  59. while(!G.empty()) {
  60. x=G.top().x; t=G.top().p; dx=G.top().d; G.pop();//忘记pop
  61. if(dx!=dis[x][t]) continue;
  62. for(y=1;y<=pos;++y) {
  63. if(find(y)!=find(S)&&find(y)!=find(T)) ad=(db)node[y].k*0.5;//忘记(db)
  64. else ad=0;
  65. if(d[x][y]==0) {
  66. if(dis[y][0]<=dx+ad) continue;
  67. dis[y][0]=dx+ad;
  68. G.push(Di(y,0,dis[y][0]));
  69. }
  70. else if(node[y].k&&node[x].k>t&&dis[y][1]>dx+d[x][y]+ad-1) {//t与dx搞混
  71. dis[y][1]=dx+d[x][y]+ad-1;
  72. G.push(Di(y,1,dis[y][1]));
  73. }
  74. }
  75. }
  76. ans=min(ans,min(dis[T][0],dis[T][1])+rs);
  77. }
  78. int main() {
  79. n=read();m=read();
  80. for(int i=1;i<=n;++i) {
  81. node[i].x=read();
  82. node[i].y=read();
  83. node[i].z=read();
  84. node[i].k=read();
  85. node[i].id=i;
  86. }
  87. sort(node+1,node+n+1,cmp);
  88. for(int i=1;i<=n;++i) p[node[i].id]=i;
  89. S=p[1];T=p[n];
  90. h=max(node[S].z,node[T].z);
  91. for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j)
  92. d[i][j]=d[j][i]=get_dis(i,j);
  93. for(int i=1;i<=n;++i) fa[i]=i;
  94. int x,y;
  95. for(int i=1;i<=m;++i) {
  96. x=p[read()]; y=p[read()];
  97. d[x][y]=d[y][x]=0;
  98. add(x,y);
  99. }
  100. for(int i=1;i<=n;++i) {
  101. for(int j=fir[i];j;j=nxt[j])
  102. if(to[j]<i) fa[find(to[j])]=find(i);
  103. for(int j=1;j<=i;++j) if(!vis[j]) {//上面的联通可能会导致下面的有些点与S、T联通
  104. x=find(j);
  105. if(x==find(S)||x==find(T)) {
  106. now+=node[j].k; vis[j]=1;//j打成i
  107. }
  108. }
  109. if(node[i].z<h||(i!=n&&node[i].z==node[i+1].z)) continue;
  110. get_ans(i);
  111. }
  112. if(ans!=INF) printf("Case 1: %.4f",ans);
  113. else printf("Case 1: impossible");
  114. return 0;
  115. }

08 test 1208 T1 A

计算几何题
求能够构成的的个数,暴力代码:

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define db double
  10. #define ll long long
  11. const int maxn=2333+10;
  12. const db eps=1e-11;
  13. int n;
  14. ll tot[3],ans;
  15. int aa,ff;char cc;
  16. int read() {
  17. aa=0;ff=1;cc=getchar();
  18. while(cc<'0'||cc>'9') {
  19. if(cc=='-') ff=-1;//忘记判断负数情况
  20. cc=getchar();
  21. }
  22. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  23. return aa*ff;
  24. }
  25. struct Node {
  26. db x,y;
  27. }node[maxn];
  28. db xx,yy,x2,y2;
  29. db X_(int i,int j,int k) {
  30. xx=node[j].x-node[i].x;x2=node[k].x-node[i].x;
  31. yy=node[j].y-node[i].y;y2=node[k].y-node[i].y;
  32. return xx*y2-yy*x2;
  33. }
  34. db D_(int i,int j,int k) {
  35. xx=node[j].x-node[i].x;x2=node[k].x-node[i].x;
  36. yy=node[j].y-node[i].y;y2=node[k].y-node[i].y;
  37. return xx*x2+yy*y2;
  38. }
  39. int main() {
  40. n=read();
  41. for(int i=1;i<=n;++i) node[i].x=read(),node[i].y=read();
  42. for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) {
  43. tot[1]=tot[2]=0;
  44. for(int k=1;k<=n;++k) if(k!=i&&k!=j) {
  45. if(X_(i,j,k)+eps<0&&D_(i,j,k)+eps>=0) ++tot[1];
  46. else if(X_(i,j,k)-eps>0&&D_(j,i,k)+eps>=0) ++tot[2];
  47. }
  48. ans+=tot[1]*tot[2];
  49. }
  50. printf("%lld",ans);
  51. return 0;
  52. }

09 hdu 5126 star

cdq套cdq裸题

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=4e5+10;
  10. int T,n,tot,qtot,ans[maxn/6];
  11. int pz[maxn/4],tz;
  12. int aa;char cc;
  13. int read() {
  14. aa=0;cc=getchar();
  15. while(cc<'0'||cc>'9') cc=getchar();
  16. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  17. return aa;
  18. }
  19. int ef(int x) {
  20. int l=1,r=tz,mid;
  21. while(l<=r) {
  22. mid=(l+r)>>1;
  23. if(pz[mid]==x) return mid;
  24. if(pz[mid]<x) l=mid+1;
  25. else r=mid-1;
  26. }
  27. }
  28. int xx[maxn],yy[maxn],zz[maxn],fnum[maxn];
  29. struct Ask{
  30. int qid,id;
  31. }ask[maxn],ask1[maxn],ask2[maxn];
  32. bool cmp(const Ask& a,const Ask& b) {
  33. return xx[a.id]==xx[b.id]? a.id < b.id : xx[a.id] < xx[b.id];//相同时必须比较id否则会挂
  34. }
  35. bool cmp2(const Ask& a,const Ask& b) {
  36. return yy[a.id]==yy[b.id]? a.id < b.id : yy[a.id] < yy[b.id];
  37. }
  38. void add(int x,int y,int z,int num) {
  39. fnum[++tot]=num;ask[tot].id=tot;
  40. xx[tot]=x;yy[tot]=y;zz[tot]=z;
  41. if(num) ask[tot].qid=qtot;
  42. }
  43. int sz[maxn];
  44. int q(int pos) {
  45. int rs=0;
  46. while(pos) {
  47. rs+=sz[pos];
  48. pos-=pos&-pos;
  49. }
  50. return rs;
  51. }
  52. void chge(int pos,int x) {
  53. while(pos<=tz) {
  54. sz[pos]+=x;
  55. pos+=pos&-pos;
  56. }
  57. }
  58. void cdq2(int l,int r) {
  59. if(l>=r) return;
  60. int mid=(l+r)>>1,now=0;
  61. cdq2(l,mid); cdq2(mid+1,r);
  62. for(int i=l;i<=mid;++i) if(!fnum[ask1[i].id]) ask2[++now]=ask1[i];
  63. for(int i=mid+1;i<=r;++i) if(fnum[ask1[i].id]) ask2[++now]=ask1[i];
  64. sort(ask2+1,ask2+now+1,cmp2);
  65. for(int i=1;i<=now;++i) {
  66. if(!fnum[ask2[i].id]) chge(zz[ask2[i].id],1);
  67. else ans[ask2[i].qid]+=fnum[ask2[i].id]*q(zz[ask2[i].id]);
  68. }
  69. for(int i=1;i<=now;++i) if(!fnum[ask2[i].id]) chge(zz[ask2[i].id],-1);
  70. }
  71. void cdq(int l,int r) {
  72. if(l>=r) return;
  73. int mid=(l+r)>>1,now=0;
  74. cdq(l,mid); cdq(mid+1,r);
  75. for(register int i=l;i<=mid;++i) if(!fnum[ask[i].id]) ask1[++now]=ask[i];
  76. for(register int i=mid+1;i<=r;++i) if(fnum[ask[i].id]) ask1[++now]=ask[i];
  77. sort(ask1+1,ask1+now+1,cmp);
  78. cdq2(1,now);
  79. }
  80. void clear() {
  81. memset(ans,0,sizeof(ans));
  82. tz=tot=qtot=0;
  83. }
  84. int main() {//提交的时候忘记关freopen
  85. T=read();
  86. int op,x,y,z,x1,y1,z1;
  87. while(T--) {
  88. n=read(); clear();
  89. for(int i=1;i<=n;++i) {
  90. op=read(); x=read(); y=read(); z=read();
  91. if(op==1) add(x,y,z,0),pz[++tz]=z;
  92. else {
  93. x1=read();y1=read();z1=read();++qtot; pz[++tz]=z1; pz[++tz]=z-1;
  94. add(x-1,y-1,z-1,-1); add(x1,y1,z1,1);
  95. add(x1,y-1,z-1,1); add(x-1,y1,z-1,1); add(x-1,y-1,z1,1);
  96. add(x-1,y1,z1,-1); add(x1,y-1,z1,-1); add(x1,y1,z-1,-1);//x、y、z需要-1
  97. }
  98. }
  99. sort(pz+1,pz+tz+1);//忘记sort了
  100. tz=unique(pz+1,pz+tz+1)-(pz+1);
  101. for(int i=1;i<=tot;++i) zz[i]=ef(zz[i]);//提前离散化跑得更快
  102. cdq(1,tot);
  103. for(int i=1;i<=qtot;++i) printf("%d\n",ans[i]);
  104. }
  105. return 0;
  106. }

11 test 1211 T3 C

一个裸的基环树+gcd
需要注意一些细节问题.

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. const int maxn=1e5+10;
  11. int n,m,hst;ll d;
  12. ll aa;char cc;
  13. ll read() {
  14. aa=0;cc=getchar();
  15. while(cc<'0'||cc>'9') cc=getchar();
  16. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  17. return aa;
  18. }
  19. int fir[maxn],nxt[2*maxn],to[2*maxn],e=1;ll v[2*maxn];
  20. void add(int x,int y,ll z) {
  21. to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;
  22. to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=-z;
  23. }
  24. int zz[maxn],t,inh[maxn],vis[maxn];
  25. void dfs1(int pos,int p) {
  26. if(vis[pos]) {
  27. while(t&&zz[t]!=pos) inh[zz[t--]]=1;
  28. hst=pos; inh[pos]=1;
  29. return ;//忘了return直接段错误
  30. }
  31. vis[pos]=1; zz[++t]=pos;
  32. for(int y=fir[pos];y;y=nxt[y]) {
  33. if(y==p) continue;
  34. dfs1(to[y],y^1);
  35. }
  36. }
  37. ll dis[maxn],toth,fa[maxn];
  38. void dfs3(int pos,ll d,ll bel) {
  39. dis[pos]=d;fa[pos]=bel;vis[pos]=1;
  40. for(int y=fir[pos];y;y=nxt[y]) {
  41. if(vis[to[y]]) continue;
  42. dfs3(to[y],d+v[y],bel);
  43. }
  44. }
  45. void dfs2(int pos,ll d,int p) {
  46. dis[pos]=d;fa[pos]=pos;vis[pos]=1;
  47. for(int y=fir[pos];y;y=nxt[y]) {
  48. if(y==p) continue;
  49. if(!inh[to[y]]) dfs3(to[y],v[y],pos);
  50. else {
  51. if(vis[to[y]]) {
  52. if(to[y]==hst) toth=d+v[y];
  53. continue;
  54. }
  55. inh[to[y]]=inh[pos]+1;
  56. dfs2(to[y],d+v[y],y^1);
  57. }
  58. }
  59. }
  60. ll get_d(int x,int y) {
  61. if(x==y) return 0;
  62. if(inh[y]>inh[x]) return dis[y]-dis[x];
  63. return -toth+(dis[y]-dis[x]);//正负号弄反
  64. }
  65. ll gcd(ll x,ll y) {
  66. return y==0? x:gcd(y,x%y);
  67. }
  68. int main() {
  69. n=read(); ll x,y,z,now;
  70. for(int i=1;i<=n;++i) {
  71. x=read(); y=read(); z=read();
  72. add(x,y,z);
  73. }
  74. dfs1(1,0);
  75. memset(vis,0,sizeof(vis));
  76. dfs2(hst,0,0);
  77. m=read();
  78. for(int i=1;i<=m;++i) {
  79. x=read();y=read();z=read();d=0;
  80. if(fa[x]!=x) d-=dis[x];
  81. if(fa[y]!=y) d+=dis[y];
  82. d+=get_d(fa[x],fa[y]);
  83. d%=z; now=toth%z;
  84. if(d<=0) d+=z;
  85. if(now<=0) now+=z;
  86. now=gcd(now,z);
  87. d%=now;if(!d) d+=now;
  88. if((z-d)%now==0) printf("%lld\n",z-now);//必须特判否则挂
  89. else printf("%lld\n",((z-d)/now)*now+d);
  90. }
  91. return 0;
  92. }

12 test 1212 T1 A

Meet in the middle模板题
因为是无向图,所以可以把从i点到其他点可以得到的二进制数的问题转化为从其他点到i点可以得到的二进制数,所以对于第二个dp就很好处理了.
改题的时候T了一发

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. const int maxn=97,maxm=2e4+7,maxt=(1<<10)|3;//maxm开小了,T
  11. int n,m,d,totans,sz1,sz2;
  12. bool dp1[2][maxn][maxt],dp2[2][maxn][maxt];
  13. int aa;char cc;
  14. int read() {
  15. aa=0;cc=getchar();
  16. while(cc<'0'||cc>'9') cc=getchar();
  17. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  18. return aa;
  19. }
  20. int fir[maxn],nxt[maxm],to[maxm],v[maxm],e=1;
  21. void add(int x,int y,int z) {
  22. to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z;
  23. to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=z;
  24. }
  25. bool vis[(1<<21)|5];int ans;
  26. void get_ans(int x) {
  27. if(!vis[x]) ++ans,vis[x]=1;
  28. }
  29. int main() {
  30. n=read(); m=read(); d=read();
  31. int x,y,z;
  32. for(int i=1;i<=m;++i) {
  33. x=read(); y=read(); z=read();
  34. add(x,y,z);
  35. }
  36. sz1=d/2; sz2=d-sz1;
  37. int p1=0,p2=0;
  38. dp1[0][1][0]=1;
  39. for(int s=1;s<=sz1;++s) {
  40. p1^=1;
  41. memset(dp1[p1],0,sizeof(dp1[p1]));
  42. for(int t=0;t<(1<<s-1);++t) for(int i=1;i<=n;++i) {
  43. if(dp1[p1^1][i][t]) for(int j=fir[i];j;j=nxt[j]) dp1[p1][to[j]][(t<<1)|v[j]]=1;
  44. }
  45. }
  46. for(int i=1;i<=n;++i) dp2[0][i][0]=1;
  47. for(int s=1;s<=sz2;++s) {
  48. p2^=1;
  49. memset(dp2[p2],0,sizeof(dp2[p2]));
  50. for(int t=0;t<(1<<s-1);++t) for(int i=1;i<=n;++i) {
  51. if(dp2[p2^1][i][t]) for(int j=fir[i];j;j=nxt[j]) dp2[p2][to[j]][(t<<1)|v[j]]=1;
  52. }
  53. }
  54. for(int i=1;i<=n;++i) for(int t=0;t<(1<<sz1);++t) if(dp1[p1][i][t]) {
  55. for(int tt=0;tt<(1<<sz2);++tt) if(dp2[p2][i][tt]) get_ans(t<<sz2|tt);
  56. }
  57. printf("%d\n",ans);
  58. return 0;
  59. }

12 test 1212 T2 B

一道sb题,但是场上sb了.
改题的时候发现题解所说的单调队列并不需要.
然后就自己随便搞了搞,跑得飞快(比std快3倍).
写了两个版本的代码,分别debug,特别难受,后来,,,
随便放一个跑得快的.

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. const int maxn=2000+7;
  11. int n,m,k,up[maxn][maxn],down[maxn][maxn],ans,nowans[maxn][maxn],p[maxn];
  12. bool ok[maxn][maxn];
  13. ll aa;char cc;
  14. ll read() {
  15. aa=0;cc=getchar();
  16. while(cc<'0'||cc>'9') cc=getchar();
  17. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  18. return aa;
  19. }
  20. struct Ask{
  21. int x,y;
  22. }ask[maxn];
  23. int f[maxn][maxn],g[maxn][maxn];
  24. bool check(int x,int y,int t) {
  25. if(t>m||t>n) return 0;
  26. int l=y,r=y,pos1,pos2,now1,now2;
  27. f[x][y]=up[x][y];g[x][y]=down[x][y];//一开始g也用的up赋值
  28. now1=up[x][y]; now2=down[x][y];
  29. while(now1+now2-1>=t&&l) {
  30. l--;
  31. now1=min(now1,up[x][l]);
  32. now2=min(now2,down[x][l]);
  33. f[x][l]=now1;g[x][l]=now2;
  34. }
  35. l++;
  36. now1=up[x][y]; now2=down[x][y];
  37. while(now1+now2-1>=t&&r<=m) {
  38. r++;
  39. now1=min(now1,up[x][r]);
  40. now2=min(now2,down[x][r]);
  41. f[x][r]=now1;g[x][r]=now2;
  42. }
  43. r--;
  44. if(r-l+1<t) return 0;
  45. pos1=l;
  46. for(pos2=y;pos2<=r&&f[x][pos2]+g[x][pos2]-1>=t;++pos2) {
  47. while(min(f[x][pos1],f[x][pos2])+min(g[x][pos1],g[x][pos2])-1<t) pos1++;
  48. if(pos2-pos1+1>=t) return 1;
  49. }
  50. pos2=r;
  51. for(pos1=y;pos1>=l&&f[x][pos1]+g[x][pos1]-1>=t;--pos1) {
  52. while(min(f[x][pos1],f[x][pos2])+min(g[x][pos1],g[x][pos2])-1<t) pos2--;
  53. if(pos2-pos1+1>=t) return 1;
  54. }
  55. return 0;
  56. }
  57. int main() {
  58. n=read(); m=read(); k=read();
  59. for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) {
  60. do cc=getchar();while(cc!='X'&&cc!='.');
  61. if(cc=='X') ok[i][j]=1;
  62. }
  63. for(int i=1;i<=k;++i) {
  64. ask[i].x=read(); ask[i].y=read();
  65. ok[ask[i].x][ask[i].y]=1;
  66. }
  67. 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;
  68. 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;
  69. for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) {
  70. if(ok[i][j]) nowans[i][j]=0;
  71. else nowans[i][j]=min(nowans[i-1][j-1],min(nowans[i-1][j],nowans[i][j-1]))+1;
  72. ans=max(ans,nowans[i][j]);
  73. }
  74. p[k]=ans;
  75. int x,y,l,r,len1,len2;
  76. for(int qaq=k;qaq>1;--qaq) {
  77. x=ask[qaq].x;y=ask[qaq].y;
  78. ok[x][y]=0;
  79. for(int i=x;i<=n&&!ok[i][y];++i) up[i][y]=up[i-1][y]+1;
  80. for(int i=x;i&&!ok[i][y];--i) down[i][y]=down[i+1][y]+1;//曾把x和y弄错
  81. while(check(x,y,ans+1)) ++ans;
  82. p[qaq-1]=ans;
  83. }
  84. for(int i=1;i<=k;++i) printf("%d\n",p[i]);
  85. return 0;
  86. }

12 test 1212night T1 A

一道网络流解决可行流的问题,场上连了负边特别难受.

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. const ll maxn=200+10,maxm=1000+10,INF=1e9;//数组开小了
  11. ll n,m,S,T,ind[maxn];
  12. ll ans;
  13. ll aa;char cc;
  14. ll read() {
  15. aa=0;cc=getchar();
  16. while(cc<'0'||cc>'9') cc=getchar();
  17. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  18. return aa;
  19. }
  20. struct Node{
  21. int x,y;ll cap,flow,w;
  22. Node(){}
  23. Node(int x,int y,ll cap,ll w):x(x),y(y),cap(cap),w(w){flow=0;}
  24. }node[2*maxm];
  25. int fir[maxn],nxt[2*maxm],e=1;
  26. void add(int x,int y,ll z,ll w) {
  27. node[++e]=Node(x,y,z,w); nxt[e]=fir[x]; fir[x]=e;
  28. node[++e]=Node(y,x,0,-w); nxt[e]=fir[y];fir[y]=e;
  29. }
  30. ll zz[maxn],dis[maxn],from[maxn];
  31. bool vis[maxn];
  32. bool spfa() {
  33. for(int i=1;i<=n+2;++i) dis[i]=INF,from[i]=0;//写成了i<=n
  34. int s=1,t=0,x,y,z,o;
  35. dis[S]=0; zz[++t]=S;vis[S]=1;
  36. while(s<=t) {
  37. x=zz[s%maxn];s++; vis[x]=0;
  38. for(y=fir[x];y;y=nxt[y]) {
  39. z=node[y].y;
  40. if(node[y].flow>=node[y].cap||dis[z]<=dis[x]+node[y].w) continue;
  41. dis[z]=dis[x]+node[y].w;
  42. from[z]=y;
  43. if(!vis[z]) {
  44. vis[z]=1; t++;
  45. zz[t%maxn]=z;
  46. }
  47. }
  48. }
  49. return dis[T]<INF;//一开始建负边的时候写的<0后来忘了改回来
  50. }
  51. ll MCMF() {
  52. ll rs=0,now;
  53. while(spfa()) {
  54. now=INF;
  55. for(int x=T;x!=S;x=node[from[x]].x) now=min(now,node[from[x]].cap-node[from[x]].flow);
  56. for(int x=T;x!=S;x=node[from[x]].x) {
  57. rs+=now*node[from[x]].w;
  58. node[from[x]].flow+=now;
  59. node[from[x]^1].flow-=now;
  60. }
  61. }
  62. return rs;
  63. }
  64. int main() {
  65. n=read(); m=read();
  66. int x,y,f,c; S=n+1;T=n+2;
  67. for(int i=1;i<=m;++i) {
  68. x=read(); y=read(); c=read(); f=read();
  69. ind[y]+=f; ind[x]-=f;
  70. if(f<=c) {
  71. add(y,x,f,1);
  72. if(f!=c) add(x,y,c-f,1);
  73. add(x,y,INF,2);
  74. }
  75. else {
  76. ans+=f-c;
  77. add(y,x,f-c,0);
  78. add(y,x,c,1);
  79. add(x,y,INF,2);
  80. }
  81. }
  82. for(int i=1;i<=n;++i) {
  83. if(ind[i]<0) add(i,T,-ind[i],0);
  84. else if(ind[i]>0) add(S,i,ind[i],0);
  85. }
  86. add(n,1,INF,0);
  87. ans+=MCMF();
  88. printf("%lld",ans);
  89. return 0;
  90. }

19 test 1219 T3 澳洲稻草人

逐渐明白样例是多么水的东西,对拍是多么优秀的东西

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. const int maxn=2e5+10;
  11. int n,p1[maxn],p2[maxn],t1,t2;ll ans;
  12. int aa;char cc;
  13. int read() {
  14. aa=0;cc=getchar();
  15. while(cc<'0'||cc>'9') cc=getchar();
  16. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  17. return aa;
  18. }
  19. int now[maxn];
  20. struct Node{
  21. int x,y,id;
  22. }node[maxn];
  23. bool cmp(const Node& a,const Node& b) {
  24. return a.x < b.x;
  25. }
  26. bool cmp2(const Node& a,const Node& b) {
  27. return now[a.y] < now[b.y];
  28. }
  29. int ef(int x,int *p,int r) {
  30. int l=1,mid;
  31. while(l<=r) {
  32. mid=(l+r)>>1;
  33. if(p[mid]==x) return mid;
  34. if(p[mid]<x) l=mid+1;
  35. else r=mid-1;
  36. }
  37. }
  38. int zz[2][maxn];
  39. int ef2(int x) {
  40. int l=0,r=t1,mid;
  41. if(node[zz[0][r]].x<x) return r+1;//一开始写特判t1=0的情况写错了
  42. while(l<r-1) {
  43. mid=(l+r)>>1;
  44. if(node[zz[0][mid]].x>x) r=mid;//栈里面放的是标号而不是直接的x
  45. else l=mid;
  46. }
  47. return r;
  48. }
  49. void add(int p,int x) {
  50. if(!p) {
  51. while(t1&&node[zz[0][t1]].y<=node[x].y) --t1;//栈里面放标号,按照y递减
  52. zz[0][++t1]=x;
  53. }
  54. else {
  55. while(t2&&node[zz[1][t2]].y>=node[x].y) --t2;
  56. zz[1][++t2]=x;//++写成--了
  57. if(t2>1) ans+=(ll)t1-(ll)ef2(node[zz[1][t2-1]].x)+1;
  58. else ans+=t1;
  59. }
  60. }
  61. void cdq(int l,int r) {
  62. if(l==r) return; t1=0; t2=0;
  63. int mid=(l+r)>>1,pos1=l,pos2=mid+1;
  64. for(int i=l;i<=r;++i) {
  65. if(node[i].y<=mid) add(0,i),now[node[i].y]=++pos1;
  66. else add(1,i),now[node[i].y]=++pos2;
  67. }
  68. sort(node+l,node+r+1,cmp2);
  69. cdq(l,mid); cdq(mid+1,r);
  70. }
  71. int main() {
  72. freopen("scarecrows.in","r",stdin);
  73. freopen("scarecrows.out","w",stdout);
  74. n=read();
  75. for(int i=1;i<=n;++i) {
  76. p1[++t1]=node[i].x=read();
  77. p2[++t2]=node[i].y=read();
  78. }
  79. sort(p1+1,p1+t1+1);
  80. sort(p2+1,p2+t2+1);
  81. for(int i=1;i<=n;++i) {
  82. node[i].x=ef(node[i].x,p1,t1);
  83. node[i].y=ef(node[i].y,p2,t2);
  84. }
  85. sort(node+1,node+n+1,cmp);
  86. cdq(1,n);
  87. printf("%lld",ans);
  88. return 0;
  89. }

28 test 1228 T1 可做题1

一道数学题
没什么好说的就是忘了取模,做题的时候一定要注意数据范围

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. ll T,p,n,m;
  11. ll f[3],g[3][3],f2[3],g2[3][3];
  12. ll aa;char cc;
  13. ll read() {
  14. aa=0;cc=getchar();
  15. while(cc<'0'||cc>'9') cc=getchar();
  16. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  17. return aa;
  18. }
  19. ll gcd(ll x,ll y) {
  20. return y==0? x:gcd(y,x%y);
  21. }
  22. void cf1() {
  23. memcpy(f2,f,sizeof(f));
  24. f[1]=f2[1]*g[1][1]%p+f2[2]*g[2][1]%p;
  25. f[2]=f2[1]*g[1][2]%p+f2[2]*g[2][2]%p;
  26. if(f[1]>=p) f[1]-=p;
  27. if(f[2]>=p) f[2]-=p;
  28. }
  29. void cf2() {
  30. memcpy(g2,g,sizeof(g));
  31. memset(g,0,sizeof(g));
  32. for(int i=1;i<=2;++i) for(int j=1;j<=2;++j) for(int k=1;k<=2;++k) {
  33. g[i][j]+=g2[i][k]*g2[k][j]%p;
  34. if(g[i][j]>=p) g[i][j]-=p;
  35. }
  36. }
  37. void qpz(ll k) {
  38. f[1]=f[2]=1; g[1][1]=0;
  39. g[1][2]=g[2][1]=g[2][2]=1;
  40. while(k) {
  41. if(k&1) cf1();
  42. cf2(); k>>=1;
  43. }
  44. }
  45. ll qp(ll x,ll k) {
  46. ll rs=1;
  47. while(k) {
  48. if(k&1) rs=rs*x%p;
  49. k>>=1; x=x*x%p;
  50. }
  51. return rs;
  52. }
  53. void exgcd(ll a,ll b,ll &x,ll &y) {
  54. if(!b) {
  55. x=1; y=0;
  56. return;
  57. }
  58. exgcd(b,a%b,y,x);
  59. y-=(a/b)*x;
  60. }
  61. ll get_ans(ll r,ll x,ll b) {
  62. if(r<0) return 0;
  63. ll rs=r/b;
  64. if(r%b>=x) rs++;
  65. return rs;
  66. }
  67. int main() {
  68. freopen("1.in","r",stdin);
  69. freopen("test.out","w",stdout);
  70. T=read();ll x,y,a,b,c,o,l,r,w;
  71. while(T--) {
  72. w=read(); l=read(); r=read();
  73. n=read(); p=read(); m=read();
  74. qpz(n-3);
  75. a=f[2]; b=p; c=(m%p-w%p*f[1]%p+p)%p;//
  76. if(c%(o=gcd(a,b))) {
  77. printf("0\n"); continue;
  78. }
  79. a/=o; b/=o; c/=o;
  80. exgcd(a,b,x,y); x*=c;
  81. x%=b; if(x<0) x+=b;
  82. printf("%lld\n",get_ans(r,x,b)-get_ans(l-1,x,b));
  83. }
  84. fclose(stdin);fclose(stdout);
  85. return 0;
  86. }
  87. /*
  88. 1
  89. 692858490132927148 33 93 11 90 52
  90. */

28 test 1228 T3

网络流题,给一些前缀和后缀,每个前缀或后缀都有一个代价,你需要用最小的代价覆盖所有的数字。
先对前缀和后缀各建一个字典树,然后直接在字典树上建图跑最大流(最小割)。

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=800+7,maxm=maxn*maxn,INF=0x3f3f3f3f;//
  10. int n,m,a[maxn],len,S,T;
  11. bool ok[maxn];
  12. char c[23],s[23];
  13. int aa;char cc;
  14. int read() {
  15. aa=0;cc=getchar();
  16. while(cc<'0'||cc>'9') cc=getchar();
  17. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  18. return aa;
  19. }
  20. //////////////////////////////////////////////////////////////Dinic
  21. struct Node{
  22. int x,y,flow,cap;
  23. Node(){}
  24. Node(int x,int y,int cap):x(x),y(y),cap(cap){flow=0;}
  25. }node[2*maxm];
  26. int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
  27. int ind[maxn];
  28. void add(int x,int y,int z) {
  29. // printf("add: %d -> %d cap:%d\n",x,y,z);
  30. node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
  31. node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
  32. }
  33. int dis[maxn],zz[maxn];
  34. bool BFS() {
  35. memset(dis,-1,sizeof(dis));
  36. int x,y,z,s=1,t=0;
  37. zz[++t]=S; dis[S]=1;
  38. while(s<=t) {
  39. x=zz[s++];
  40. for(y=fir[x];y;y=nxt[y]) {
  41. if(dis[z=node[y].y]!=-1||node[y].flow>=node[y].cap) continue;
  42. dis[z]=dis[x]+1;
  43. zz[++t]=z;
  44. }
  45. }
  46. return dis[T]!=-1;
  47. }
  48. int DFS(int pos,int maxf) {
  49. if(pos==T||!maxf) return maxf;
  50. int z,now,rs=0;
  51. for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
  52. if(dis[z=node[y].y]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
  53. now=DFS(z,min(maxf,node[y].cap-node[y].flow));
  54. node[y].flow+=now;
  55. node[y^1].flow-=now;
  56. rs+=now; maxf-=now;
  57. }
  58. if(!rs) dis[pos]=-1;
  59. return rs;
  60. }
  61. int Dinic() {
  62. int rs=0;
  63. while(BFS()) {
  64. memcpy(cur,fir,sizeof(fir));
  65. rs+=DFS(S,INF);
  66. }
  67. return rs;
  68. }
  69. ////////////////////////////////////////////////////////////////
  70. bool check(int r,int x,int p,int len) {
  71. if(p==0) return (r>>(8-len))==x;
  72. else {
  73. r&=((1<<len)-1);
  74. return r==x;
  75. }
  76. }
  77. int le[maxn],num[maxn],cost[maxn];
  78. int t[2]={1,1};
  79. struct G{
  80. int num,son[2];
  81. }g[2][maxn*4];
  82. void insert(int p,int x,int len,int i) {
  83. int now=1,r;
  84. if(!p) {
  85. int xx=x; x=0;
  86. for(int i=1;i<=len;++i,xx>>=1) {
  87. x<<=1;
  88. x+=(xx&1);
  89. }
  90. }
  91. while(len--) {
  92. r=x&1; x>>=1;
  93. if(!g[p][now].son[r]) g[p][now].son[r]=++t[p];
  94. now=g[p][now].son[r];
  95. }
  96. if(!g[p][now].num) g[p][now].num=i;
  97. else if(cost[g[p][now].num] > cost[i]) g[p][now].num=i;
  98. }
  99. void dfs1(int pos,int f) {
  100. if(!pos) return;
  101. int id=g[0][pos].num;
  102. if(id) add(f,n+id,cost[id]),f=id+n;//
  103. dfs1(g[0][pos].son[0],f);
  104. dfs1(g[0][pos].son[1],f);
  105. if(id) {
  106. for(int j=1;j<=n;++j) if((!ok[j])&&check(a[j],num[id],0,le[id])) {
  107. ok[j]=1; add(n+id,j,INF);
  108. }
  109. }
  110. }
  111. void dfs2(int pos,int f) {
  112. if(!pos) return;
  113. int id=g[1][pos].num;
  114. if(id) add(n+id,f,cost[id]),f=id+n;
  115. dfs2(g[1][pos].son[0],f);
  116. dfs2(g[1][pos].son[1],f);
  117. if(id) {
  118. for(int j=1;j<=n;++j) if((!ok[j])&&check(a[j],num[id],1,le[id])) {
  119. ok[j]=1; add(j,n+id,INF);
  120. }
  121. }
  122. }
  123. int main() {
  124. freopen("C.in","r",stdin);
  125. freopen("C.out","w",stdout);
  126. n=read(); m=read(); int x,p;
  127. S=n+m+1; T=S+1;
  128. memset(g,0,sizeof(g));
  129. for(int i=1;i<=n;++i) a[i]=read();
  130. for(int i=1;i<=m;++i) {
  131. scanf("%s%s",c+1,s+1);
  132. cost[i]=read();
  133. le[i]=len=strlen(s+1);
  134. x=0; p= c[1]=='S';//0前缀 1后缀
  135. for(int j=1;j<=len;++j) {
  136. x<<=1;
  137. x+=(s[j]-'0');
  138. }
  139. num[i]=x;
  140. for(int j=1;j<=n;++j) if(check(a[j],x,p,len)) ok[j]=1;
  141. insert(p,x,len,i);
  142. }
  143. for(int i=2;i<=n;++i) ok[1]&=ok[i];
  144. if(!ok[1]) printf("-1");
  145. else {
  146. memset(ok,0,sizeof(ok));
  147. dfs1(1,S);
  148. for(int i=1;i<=n;++i) if(!ok[i]) add(S,i,INF);//一开始没有考虑到
  149. memset(ok,0,sizeof(ok));
  150. dfs2(1,T);
  151. for(int i=1;i<=n;++i) if(!ok[i]) add(i,T,INF);
  152. printf("%d\n",Dinic());
  153. }
  154. fclose(stdin); fclose(stdout);
  155. return 0;
  156. }
  157. /*
  158. 8 7
  159. 0 1 2 3 4 5 6 6
  160. P 000001 3
  161. P 0000000 2
  162. P 0000010 1
  163. P 0000000 1
  164. S 10 1
  165. S 11 1
  166. S 00 1
  167. S 01 1
  168. */

29 test 1208 T2 BG的保险箱

一个模意义下开根的模板题。第一次写,还是debug了一个小时。

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. ll T,n,p,ans;
  11. ll f[3],g[3][3],f2[3],g2[3][3];
  12. ll aa;char cc;
  13. ll read() {
  14. aa=0;cc=getchar();
  15. while(cc<'0'||cc>'9') cc=getchar();
  16. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  17. return aa;
  18. }
  19. void cf1() {
  20. memcpy(f2,f,sizeof(f));
  21. f[1]=f2[1]*g[1][1]%p+f2[2]*g[2][1]%p;
  22. f[2]=f2[1]*g[1][2]%p+f2[2]*g[2][2]%p;
  23. if(f[1]>=p) f[1]-=p;
  24. if(f[2]>=p) f[2]-=p;
  25. }
  26. void cf2() {
  27. memcpy(g2,g,sizeof(g));
  28. memset(g,0,sizeof(g));
  29. for(int i=1;i<=2;++i) for(int j=1;j<=2;++j) for(int k=1;k<=2;++k) {
  30. g[i][j]+=g2[i][k]*g2[k][j]%p;
  31. if(g[i][j]>=p) g[i][j]-=p;
  32. }
  33. }
  34. void qpz(ll k) {
  35. f[1]=f[2]=1; g[1][1]=0;
  36. g[1][2]=g[2][1]=g[2][2]=1;
  37. while(k) {
  38. if(k&1) cf1();
  39. cf2(); k>>=1;
  40. }
  41. }
  42. ll qp(ll x,ll k) {
  43. ll rs=1;
  44. while(k) {
  45. if(k&1) rs=rs*x%p;
  46. k>>=1; x=x*x%p;
  47. }
  48. return rs;
  49. }
  50. bool check(ll x) {
  51. x%=p;
  52. return qp(x,(p-1)>>1) == 1;
  53. }
  54. ll get_sq(ll x) {
  55. ll a,wpf; x%=p;
  56. do a=rand()%(2*p);while(!a||check(a*a-x));
  57. wpf=(a*a-x)%p;
  58. ll rs1=1,rs2=0,x1=a,x2=1,k=(p+1)>>1,aa,bb;//一开始x1写成了1
  59. while(k) {
  60. if(k&1) {
  61. aa=(rs1*x1%p+rs2*x2%p*wpf%p)%p;
  62. bb=(rs1*x2%p+rs2*x1%p)%p;
  63. rs1=aa; rs2=bb;
  64. }
  65. k>>=1;
  66. aa=(x1*x1%p+x2*x2%p*wpf%p)%p;
  67. bb=2*x1*x2%p;
  68. x1=aa; x2=bb;
  69. }
  70. return rs1;
  71. }
  72. int main() {
  73. srand(1031); ll a,b;
  74. T=read();
  75. while(T--) {
  76. a=read(); b=read(); n=read(); p=read();
  77. if((!check(a)||(!check(b)))) printf("0\n");
  78. else {
  79. a=get_sq(a);
  80. b=get_sq(b);
  81. p--; qpz(n-1);
  82. f[1]=f[1]*2%p; f[2]=f[2]*2%p;
  83. p++; ans=(qp((a+b+p)%p,f[2])+qp((a-b+p)%p,f[2]))%p;
  84. printf("%lld\n",ans*4%p);
  85. }
  86. }
  87. return 0;
  88. }
  89. /*
  90. 4
  91. 2 3 1 10007
  92. 2 3 2 10007
  93. 2 3 3 10007
  94. 2 3 4 10007
  95. */

2018.01

0104 练习题palindrome

和去年省选D2T3很像,但不用本质不同,而且简单很多,用后缀数组和马拉车预处理lcp和以i为开头的回文串(放到树状数组里)bug弄了一晚上

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. const int maxn=16e5+10,INF=0x3f3f3f3f;
  11. int n,m,Q,ql,qr;ll totans;
  12. char A[maxn],B[maxn],S[2*maxn];
  13. int x[maxn],y[maxn],c[maxn],sa[maxn],h[maxn],rad[maxn];
  14. ll aa;char cc;
  15. ll read() {
  16. aa=0;cc=getchar();
  17. while(cc<'0'||cc>'9') cc=getchar();
  18. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  19. return aa;
  20. }
  21. ll minnum[4*maxn];
  22. void bld(int pos,int l,int r) {
  23. if(l==r) {
  24. minnum[pos]=h[l];
  25. return;
  26. }
  27. int mid=(l+r)>>1;
  28. bld(pos<<1,l,mid); bld(pos<<1|1,mid+1,r);
  29. minnum[pos]=min(minnum[pos<<1],minnum[pos<<1|1]);
  30. }
  31. ll qmin(int pos,int l,int r) {
  32. if(l>=ql&&r<=qr) return minnum[pos];
  33. int mid=(l+r)>>1;ll rs=INF;
  34. if(ql<=mid) rs=min(rs,qmin(pos<<1,l,mid));
  35. if(qr>mid) rs=min(rs,qmin(pos<<1|1,mid+1,r));
  36. return rs;
  37. }
  38. ll tot[2][maxn],sum[2][maxn];
  39. ll q(int pos,ll *sz) {
  40. ll rs=0;
  41. while(pos) {
  42. rs+=sz[pos];
  43. pos-=pos&-pos;
  44. }
  45. return rs;
  46. }
  47. void chge(int pos,int x,ll *sz,int n) {
  48. while(pos<=n) {
  49. sz[pos]+=x;
  50. pos+=pos&-pos;
  51. }
  52. }
  53. void get_sa(char *s,int n) {
  54. int m='z'+1,p;
  55. for(int i=0;i<n;++i) c[x[i]=s[i]]++;
  56. for(int i=1;i<m;++i) c[i]+=c[i-1];
  57. for(int i=n-1;i>=0;--i) sa[--c[x[i]]]=i;
  58. for(int k=1;k<=n;k<<=1) {
  59. p=0;
  60. for(int i=n-1;i>=n-k;--i) y[p++]=i;
  61. for(int i=0;i<n;++i) if(sa[i]>=k) y[p++]=sa[i]-k;
  62. for(int i=0;i<m;++i) c[i]=0;
  63. for(int i=0;i<n;++i) c[x[y[i]]]++;
  64. for(int i=1;i<m;++i) c[i]+=c[i-1];
  65. for(int i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i];
  66. swap(x,y);p=1;
  67. x[sa[0]]=0;
  68. for(int i=1;i<n;++i)
  69. x[sa[i]]= y[sa[i]]==y[sa[i-1]]&&
  70. ((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++;
  71. if(p>=n) break; else m=p;
  72. }
  73. p=0;int u;
  74. for(int i=0;i<n;++i) {
  75. if(!x[i]) continue;
  76. u=sa[x[i]-1];
  77. if(p) p--;
  78. while(s[u+p]==s[i+p]) p++;
  79. h[x[i]]=p;
  80. }
  81. memset(minnum,0x3f3f3f3f,sizeof(minnum));
  82. bld(1,1,n-1);
  83. }
  84. void manacher(char *s,ll *sz,int len,int o) {
  85. int maxpos=0,p=0;
  86. for(int i=len;i;--i) {//不是从0开始而是从1开始
  87. s[i<<1]=s[i];
  88. s[i<<1|1]='#';
  89. }
  90. s[0]=s[1]='#';
  91. for(int i=2;i<=2*len;++i) {
  92. if(maxpos>i) rad[i]=min(maxpos-i,rad[2*p-i]);
  93. else rad[i]=0;
  94. while(i-rad[i]>0&&i+rad[i]<=2*len+1&&s[i-rad[i]]==s[i+rad[i]]) rad[i]++;
  95. rad[i]--;
  96. if(i+rad[i]>maxpos) p=i,maxpos=i+rad[i];
  97. }
  98. for(int i=2;i<=2*len;++i) {
  99. chge((i-rad[i]+1)>>1,1,tot[o],len);
  100. chge((i+2)>>1,-1,tot[o],len);
  101. }
  102. }
  103. int main() {
  104. freopen("palindrome.in","r",stdin);
  105. freopen("palindrome.out","w",stdout);
  106. scanf("%s",A+1);
  107. scanf("%s%s",A+1,B+1);
  108. n=strlen(A+1); m=strlen(B+1);
  109. for(int i=1;i<=m/2;++i) swap(B[i],B[m-i+1]);
  110. for(int i=1;i<=n;++i) S[i-1]=A[i]; S[n]='#';//n不是n+1
  111. for(int i=1;i<=m;++i) S[i+n]=B[i];
  112. get_sa(S,n+m+1);
  113. manacher(A,tot[0],n,0);
  114. manacher(B,tot[1],m,1);
  115. for(int i=1;i<=n;++i) chge(i,q(i,tot[0]),sum[0],n+1);
  116. for(int i=1;i<=m;++i) chge(i,q(i,tot[1]),sum[1],m+1);
  117. //注意是n+1和m+1,因为可能询问到
  118. Q=read();int xx,yy,len;
  119. for(int i=1;i<=Q;++i) {
  120. xx=read(); yy=read();
  121. ql=x[xx-1]; qr=x[yy+n];
  122. if(qr<ql) swap(ql,qr);
  123. ++ql;
  124. len=qmin(1,1,n+m);
  125. totans=len;
  126. totans+=q(xx+len,sum[0])-q(xx,sum[0]);
  127. totans+=q(yy+len,sum[1])-q(yy,sum[1]);//注意边界
  128. printf("%lld\n",totans);
  129. }
  130. fclose(stdin);fclose(stdout);
  131. return 0;
  132. }
  133. /*
  134. orzAchen
  135. babaabbba
  136. baaabbb
  137. 1
  138. 9 6
  139. */
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注