Codeforces Round #467 Div. 1
B:显然即相当于能否找一条有长度为奇数的路径使得终点出度为0。如果没有环直接dp即可。有环的话可以考虑死了的spfa,由于每个点我们至多只需要让其入队两次,复杂度变成了优秀的O(kE)。事实上就是拆点。方案的输出在spfa过程中记录即可。然后判一下由起点是否能走进一个环,若可以至少是平局。
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- #define ll long long
- #define N 100010
- char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
- int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
- int read()
- {
- int x=0,f=1;char c=getchar();
- while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
- while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
- return x*f;
- }
- int n,m,p[N],f[N],from[N][2],q[N],degree[N],dfn[N],size[N],t,cnt;
- bool flag[N];
- struct data{int to,nxt;
- }edge[N<<1];
- void addedge(int x,int y){t++;degree[x]++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
- int inc(int &x){x++;if (x>n+1) x-=n+1;return x;}
- void spfa(int S)
- {
- f[S]=1;q[1]=S;
- int head=0,tail=1;
- do
- {
- int x=q[inc(head)];flag[x]=0;
- for (int i=p[x];i;i=edge[i].nxt)
- if (f[edge[i].to]<3&&(f[x]==3||f[x]==f[edge[i].to]||f[edge[i].to]==0))
- {
- if (f[x]==3)
- {
- if (f[edge[i].to]==0) from[edge[i].to][0]=from[edge[i].to][1]=x;
- else from[edge[i].to][(3^f[edge[i].to])==2]=x;
- f[edge[i].to]=3;
- }
- else f[edge[i].to]|=3^f[x],from[edge[i].to][(3^f[x])==2]=x;
- if (!flag[edge[i].to])
- {
- flag[edge[i].to]=1;
- q[inc(tail)]=edge[i].to;
- }
- }
- }while (head!=tail);
- }
- void dfs1(int k)
- {
- dfn[k]=++cnt;size[k]=1;
- for (int i=p[k];i;i=edge[i].nxt)
- if (!dfn[edge[i].to]) dfs1(edge[i].to),size[k]+=size[edge[i].to];
- }
- bool dfs(int k)
- {
- flag[k]=1;
- for (int i=p[k];i;i=edge[i].nxt)
- if (flag[edge[i].to]){if (dfn[edge[i].to]<=dfn[k]&&dfn[edge[i].to]+size[edge[i].to]>dfn[k]) return 1;}
- else if (dfs(edge[i].to)) return 1;
- return 0;
- }
- void print(int k,int op)
- {
- if (k==0) return;
- print(from[k][op],op^1);
- printf("%d ",k);
- }
- signed main()
- {
- #ifndef ONLINE_JUDGE
- freopen("a.in","r",stdin);
- freopen("a.out","w",stdout);
- #endif
- n=read(),m=read();
- for (int i=1;i<=n;i++)
- {
- int x=read();
- while (x--) addedge(i,read());
- }
- int S;spfa(S=read());
- for (int i=1;i<=n;i++)
- if (!degree[i]&&(f[i]&2))
- {
- cout<<"Win"<<endl;
- print(i,1);
- return 0;
- }
- dfs1(S);memset(flag,0,sizeof(flag));
- if (dfs(S)) cout<<"Draw";else cout<<"Lose";
- return 0;
- //NOTICE LONG LONG!!!!!
- }
C:显然字符集不同时无解。考虑我们已经满足了目标字符串的前i位,现在要将第i+1位也放在正确的位置。将当前串拆成abxy四部分,a是已经安排好的位置,x是i+1位的当前位置。把已经满足的位置放在字符串末尾,即形如bxya。移动ya得到aybx(a倒序),可以直接接上x得到ayxb(原x和a合并),直接翻转整个串就回到了原状态bxya。于是我们用3步放好了一位,就做完了。sol里2.5n的也区别不大但懒得管了。构造全靠凑,原本把已经满足的位置放在了开头,结果怎么捣鼓都是3.5n,放在末尾简直一眼就出来了。
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- #define ll long long
- #define N 2010
- char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
- int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
- int read()
- {
- int x=0,f=1;char c=getchar();
- while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
- while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
- return x*f;
- }
- int n,cnt[N];
- char a[N],b[N],c[N];
- signed main()
- {
- #ifndef ONLINE_JUDGE
- freopen("a.in","r",stdin);
- freopen("a.out","w",stdout);
- #endif
- n=read();
- cin>>(a+1)>>(b+1);
- for (int i=1;i<=n;i++) cnt[a[i]]++;
- for (int i=1;i<=n;i++) cnt[b[i]]--;
- for (int i=1;i<=200;i++) if (cnt[i]) {cout<<-1;return 0;}
- cout<<n*3<<endl;
- for (int i=1;i<=n;i++)
- {
- int p=0;
- for (int j=1;j<=n;j++) if (a[j]==b[i]) {p=j;break;}
- cout<<n-p<<' '<<1<<' '<<n<<' ';
- reverse(a+p+1,a+n+1);
- for (int j=p;j<=n;j++) c[j-p+1]=a[j];
- for (int j=1;j<p;j++) c[n-p+1+j]=a[j];
- for (int j=1;j<=n;j++) a[j]=c[j];
- reverse(a+1,a+n+1);
- }
- return 0;
- //NOTICE LONG LONG!!!!!
- }
D:考虑dp出每堵墙最早在什么位置可以被破坏。要将其破坏要么得破坏其正前方的墙,要么得绕到其正前方的墙后面(显然这种情况绕到后面恰好一格最优)。第一种情况可以直接转移而来,第二种情况还需要求到达某个位置时最快还要多久才能开枪。这个东西同样考虑dp,要到这个位置要么从该行直接冲过来,要么从另一行绕过来。第一种情况考虑其正前方是否有墙,没有直接转移,有则用上面的dp值转移;第二种情况类似考虑该列另一位置有没有墙即可。
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<cstdlib>
- #include<cstring>
- #include<algorithm>
- #include<cassert>
- using namespace std;
- #define ll long long
- #define N 2000010
- #define inf 1010000000
- char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
- int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
- int read()
- {
- int x=0,f=1;char c=getchar();
- while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
- while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
- return x*f;
- }
- int n,m1,m2,t,a[N],b[N],v[N],pre[N][2],f[N][2],g[N][2],from[N][2][2],u,p[N],q[N][2];
- bool flag[N][2];
- signed main()
- {
- #ifndef ONLINE_JUDGE
- freopen("a.in","r",stdin);
- freopen("a.out","w",stdout);
- const char LL[]="%I64d\n";
- #else
- const char LL[]="%lld\n";
- #endif
- n=read(),m1=read(),m2=read(),t=read();
- for (int i=1;i<=m1;i++) v[++u]=a[i]=read(),v[++u]=a[i]+1;
- for (int i=1;i<=m2;i++) v[++u]=b[i]=read(),v[++u]=b[i]+1;
- v[++u]=1;
- sort(v+1,v+u+1);
- u=unique(v+1,v+u+1)-v-1;
- for (int i=1;i<=m1;i++) flag[a[i]=lower_bound(v+1,v+u+1,a[i])-v][0]=1;
- for (int i=1;i<=m2;i++) flag[b[i]=lower_bound(v+1,v+u+1,b[i])-v][1]=1;
- for (int i=1;i<=u;i++)
- {
- f[i][0]=f[i][1]=g[i][0]=g[i][1]=inf;
- if (flag[i-1][0]) pre[i][0]=i-1;else pre[i][0]=pre[i-1][0];
- if (flag[i-1][1]) pre[i][1]=i-1;else pre[i][1]=pre[i-1][1];
- }
- flag[0][0]=flag[0][1]=1;f[0][0]=f[0][1]=t;g[0][0]=g[0][1]=0;
- for (int i=1;i<=u;i++)
- {
- int tmp[2]={0,1};if (flag[i][1]) swap(tmp[0],tmp[1]);
- for (int qwq=0,j=tmp[qwq];qwq<2;qwq++,j=tmp[qwq])
- if (flag[i][j])
- {
- int x=pre[i][j];
- g[i][j]=g[x][j]+t;
- if (g[i][j]>=v[i]) g[i][j]=inf;
- else
- {
- f[i][j]=max(0,t-(v[i]-g[i][j]));
- from[i][j][0]=x,from[i][j][1]=j;
- }
- x++;
- if (x!=i&&f[x][j]<v[i]-v[x]&&max(0,f[x][j]-v[i]+v[x]+t)<=f[i][j])
- {
- f[i][j]=max(0,f[x][j]-v[i]+v[x]+t);
- g[i][j]=min(g[i][j],v[x]+f[x][j]);
- from[i][j][0]=x,from[i][j][1]=j;
- }
- f[i][j]=min(f[i][j],inf);
- }
- else
- {
- int x=max(0,f[i-1][j]-v[i]+v[i-1]),y=flag[i][j^1]?f[i][j^1]:max(0,f[i-1][j^1]-v[i]+v[i-1]);
- if (x<=y)
- {
- f[i][j]=x;from[i][j][0]=i-1,from[i][j][1]=j;
- }
- else
- {
- f[i][j]=y;from[i][j][0]=i,from[i][j][1]=j^1;
- }
- f[i][j]=min(f[i][j],inf);
- }
- }
- if (min(f[u][0],f[u][1])>n+59) {cout<<"No";return 0;}
- else
- {
- cout<<"Yes"<<endl;
- int x=u,y=0;if (f[x][y]>n+59) y^=1;//cout<<x<<' '<<y<<endl;
- int topp=0,topq=0;
- while (x)
- {
- if (from[x][y][1]!=y) p[++topp]=from[x][y][0];
- if (flag[x][y]) q[++topq][0]=g[x][y],q[topq][1]=y+1;
- int u=from[x][y][0],v=from[x][y][1];
- x=u,y=v;
- }
- if (y==1) p[++topp]=0;
- cout<<topp<<endl;
- for (int i=topp;i>=1;i--) printf("%d ",v[p[i]]);cout<<endl;
- cout<<topq<<endl;
- for (int i=topq;i>=1;i--) printf("%d %d\n",q[i][0],q[i][1]);
- }
- return 0;
- }
Codeforces Round #467 Div. 1的更多相关文章
- Codeforces Round #467 (div.2)
Codeforces Round #467 (div.2) 我才不会打这种比赛呢 (其实本来打算打的) 谁叫它推迟到了\(00:05\) 我爱睡觉 题解 A. Olympiad 翻译 给你若干人的成绩 ...
- Codeforces Round #467 (Div. 2) B. Vile Grasshoppers
2018-03-03 http://codeforces.com/problemset/problem/937/B B. Vile Grasshoppers time limit per test 1 ...
- Codeforces Round #467 (Div. 1) B. Sleepy Game
我一开始把题目看错了 我以为是博弈.. 这题就是一个简单的判环+dfs(不简单,挺烦的一题) #include <algorithm> #include <cstdio> #i ...
- Codeforces Round #467 (Div. 1). C - Lock Puzzle
#include <algorithm> #include <cstdio> #include <cstring> #include <iostream> ...
- Codeforces Round #467 (Div. 2) E -Lock Puzzle
Lock Puzzle 题目大意:给你两个字符串一个s,一个t,长度<=2000,要求你进行小于等于6100次的shift操作,将s变成t, shift(x)表示将字符串的最后x个字符翻转后放到 ...
- Codeforces Round #467 (Div. 2) B. Vile Grasshoppers[求去掉2-y中所有2-p的数的倍数后剩下的最大值]
B. Vile Grasshoppers time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Codeforces Round #467 (Div. 2) A. Olympiad[输入一组数,求该数列合法的子集个数]
A. Olympiad time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...
- Codeforces Round #467 Div.2题解
A. Olympiad time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
随机推荐
- 图解Redis之数据结构篇——简单动态字符串SDS
图解Redis之数据结构篇--简单动态字符串SDS 前言 相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象 ...
- git revert 还有这个坑?
最近也是终于开启了代码编写之旅,我只能默默地说一句,写代码的感觉,简直不能再爽! 不过也由于 git 的分支管理蛋疼懵逼很久,所以必须记录以及和大家分享一下本次坑爹的旅行. 写在前面 每个公司相比都有 ...
- Linux查看端口
1.lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000 2.netstat -tunlp |grep 端口号 用于查看指定的端口号的进程情况 ...
- Less or Equal CodeForces - 977C (sort+细节)
You are given a sequence of integers of length nn and integer number kk. You should print any intege ...
- 斐波那契数列yield表示
def fib(num): n=0 a,b=0,1 while n<num: print(b) yield a,b=b,a+b n=n+1a=fib(30)next(a)next(a)
- HTTP协议,Http 常用状态码
一.HTTP协议-Request HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的.HTTP有两类报文:请求报文和响应报文. 1.1 HTTP请求报 ...
- 【学习总结】Git学习-参考廖雪峰老师教程九-使用码云
学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...
- js-跨域源资源共享(CORS)
### 一. CORS(Cross-Origin Resource Sharing,跨域源资源共享) 基本思想:使用自定义HTTP头部让浏览器与服务器进行沟通 发送请求时,需附加一个Origin头部 ...
- js-XMLHttpRequest 2级
###1. XMLHttpRquest 2级 1) FormData 现代web应用中频繁使用的一项功能就死表单数据的序列化, XMLHttpRquest 2级为此定义了FormData类型 Fo ...
- vue图片被加了盗链
https://www.cnblogs.com/dongcanliang/archive/2017/04/01/6655061.html <meta name="referrer&qu ...