A:求出该行该列各有多少个比其小的取max,该行该列各有多少个比其大的取max,加起来即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 1010
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,a[N][N],ans[N][N],ans2[N][N],b[N];
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++)
for (int j=1;j<=m;j++)
a[i][j]=read();
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) b[j]=a[i][j];
sort(b+1,b+m+1);
int t=unique(b+1,b+m+1)-b-1;
for (int j=1;j<=m;j++)
{
int x=lower_bound(b+1,b+t+1,a[i][j])-b;
ans[i][j]=max(ans[i][j],x);
ans2[i][j]=max(ans2[i][j],t-x);
}
}
for (int i=1;i<=m;i++)
{
for (int j=1;j<=n;j++) b[j]=a[j][i];
sort(b+1,b+n+1);
int t=unique(b+1,b+n+1)-b-1;
for (int j=1;j<=n;j++)
{
int x=lower_bound(b+1,b+t+1,a[j][i])-b;
ans[j][i]=max(ans[j][i],x);
ans2[j][i]=max(ans2[j][i],t-x);
}
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
printf("%d ",ans[i][j]+ans2[i][j]);
printf("\n");
}
return 0;
//NOTICE LONG LONG!!!!!
}

  B:kmp求出最长border,贪心的每次利用这个border制造新子串即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 1000010
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,cnt,nxt[N],cnt2;
char a[N],b[N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
scanf("%s",a+1);n=strlen(a+1);
scanf("%s",b+1);m=strlen(b+1);
for (int i=1;i<=n;i++) if (a[i]=='1') cnt++;
for (int i=1;i<=m;i++) if (b[i]=='1') cnt2++;
nxt[0]=-1;
for (int i=1;i<=m;i++)
{
int j=nxt[i-1];
while (b[j+1]!=b[i]&&j!=-1) j=nxt[j];
nxt[i]=j+1;
}
if (n<m) {printf("%s",a+1);return 0;}
if (cnt<cnt2||n-cnt<m-cnt2) {printf("%s",a+1);return 0;}
int X=cnt,Y=n-cnt;
printf("%s",b+1);X-=cnt2,Y-=m-cnt2;
cnt=0;for (int i=nxt[m]+1;i<=m;i++) if (b[i]=='1') cnt++;
cnt2=m-nxt[m]-cnt;
while (X>=cnt&&Y>=cnt2)
{
for (int i=nxt[m]+1;i<=m;i++) putchar(b[i]);
X-=cnt,Y-=cnt2;
}
for (int i=1;i<=X;i++) printf("1");
for (int i=1;i<=Y;i++) printf("0");
return 0;
//NOTICE LONG LONG!!!!!
}

  C:场上写了1h假题意。终于看懂题之后又被之前假题意的做法带偏了。考虑拆点,建出新图后缩点,跑最长链即为答案。因为由图的特殊性容易发现,若新图中有两个点代表原图中同一个点的不同时刻且其弱联通,其一定处于同一SCC中。所以不会出现多次计算同一个点的贡献的情况。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define N 100010
#define M 54
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,d,p[N],dfn[N*M],low[N*M],stk[N*M],Set[N*M],P[N*M],nxt[N*M],top,cnt,t,ans,a[N][M];
bool flag[N*M];
struct data{int to,nxt;
}edge[N<<1];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
int id(int n,int m){return (n-1)*d+m;}
void tarjan(int x,int y)
{
int k=id(x,y);
dfn[k]=low[k]=++cnt;
stk[++top]=k;flag[k]=1;
for (int i=p[x];i;i=edge[i].nxt)
if (!dfn[id(edge[i].to,y%d+1)]) tarjan(edge[i].to,y%d+1),low[k]=min(low[k],low[id(edge[i].to,y%d+1)]);
else if (flag[id(edge[i].to,y%d+1)]) low[k]=min(low[k],dfn[id(edge[i].to,y%d+1)]);
if (dfn[k]==low[k])
{
t++;
while (stk[top]!=k)
{
nxt[stk[top]]=P[t];
P[t]=stk[top];
flag[stk[top]]=0;
Set[stk[top]]=t;
top--;
}
flag[k]=0,Set[k]=t,top--;
nxt[k]=P[t];P[t]=k;
}
}
namespace DAG
{
int p[N*M],n,t,f[N*M],value[N*M];
struct data{int to,nxt;}edge[N*M];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dp()
{
for (int i=1;i<=n;i++)
{
for (int j=p[i];j;j=edge[j].nxt)
f[i]=max(f[i],f[edge[j].to]);
f[i]+=value[i];
}
}
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read(),m=read(),d=read();
for (int i=1;i<=m;i++)
{
int x=read(),y=read();
addedge(x,y);
}
for (int i=1;i<=n;i++)
for (int j=1;j<=d;j++)
{
char c=getchar();
while (c!='0'&&c!='1') c=getchar();
a[i][j]=c-'0';
}
t=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=d;j++)
if (!dfn[id(i,j)]) tarjan(i,j);
DAG::n=t;
for (int i=1;i<=n;i++)
for (int x=1;x<=d;x++)
for (int j=p[i];j;j=edge[j].nxt)
if (Set[id(i,x)]!=Set[id(edge[j].to,x%d+1)])
DAG::addedge(Set[id(i,x)],Set[id(edge[j].to,x%d+1)]);
memset(flag,0,sizeof(flag));
for (int i=1;i<=t;i++)
{
for (int j=P[i];j;j=nxt[j])
if (!flag[(j-1)/d+1]&&a[(j-1)/d+1][(j-1)%d+1]) DAG::value[i]++,flag[(j-1)/d+1]=1;
for (int j=P[i];j;j=nxt[j]) flag[(j-1)/d+1]=0;
}
DAG::dp();
cout<<DAG::f[Set[1]];
return 0;
//NOTICE LONG LONG!!!!!
}

  D:看到这张图就容易想到floyd判环。于是先拉两个点出来跑一遍,大约能得到一个2(t+d)=t+d+kc。其中k和c都可以确定。这样大概可以二分一下t,但点数说不定不太够。事实上这个时候直接让所有点一起往前跑第一次撞上就是答案了。因为t+d=kc,当前环上点在d的位置,走t步后刚好走到终点。同时由起点出发的点也刚好走了t步到达终点。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
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;
}
char s[12];
int main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
#endif
int cnt=0;
while (1)
{
cout<<"next 1 2"<<endl;
int x=read();
for (int i=1;i<=x;i++) scanf("%s",s);
cout<<"next 1"<<endl;
x=read();
for (int i=1;i<=x;i++) scanf("%s",s);
if (x==2) break;
}
while (1)
{
cout<<"next 0 1 2 3 4 5 6 7 8 9"<<endl;
int x=read();
for (int i=1;i<=x;i++) scanf("%s",s);
if (x==1) {cout<<"done"<<endl;return 0;}
}
}

  E:显然同时被加入的车只有第一辆可能成为答案,于是可以把同一段的合并起来。先不考虑插入,就是要滋磁整体加一条直线、查最小值。经典做法是对坐标为k初值为b的位置构造一条直线y=kx+b,然后求出所有直线构成的上凸壳,显然最小值只会在凸壳上取得,每次加的时候相当于移动凸壳上当前点的横坐标。

  对于插入,如果是在尾部,相当于插入了一条当前斜率最大的直线,如果其在上凸壳中,一定处于第一个,所以在凸壳头部删直线并插入即可;如果在头部,会对所有直线的斜率产生影响,但可以发现这些直线构成的凸壳不会发生变化。于是相当于插入了一条当前斜率最小的直线,在凸壳尾部删直线并插入即可。修改时加上的常数显然可以改成偏移量处理掉。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 600010
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;
}
typedef pair<ll,ll> pll;
int m,head,tail;
ll n,first,last,deltas,deltab;
struct line
{
ll k,b;
ll f(ll x){return k*x+b;}
}a[N];
bool iscover(line x,line y,line z)
{
return (long double)(x.k-y.k)*(z.b-x.b)/(x.k-z.k)<=y.b-x.b;
}
void ins_head(ll k,ll b)
{
line l=(line){k,b};
while (head<tail&&iscover(l,a[head],a[head+1])) head++;
if (head==tail&&l.k<a[head].k&&l.b<=a[head].b) head++;
a[--head]=l;
}
void ins_tail(ll k,ll b)
{
line l=(line){k,b};
while (head<tail&&iscover(a[tail-1],a[tail],l)) tail--;
if (head==tail&&l.k<a[head].k&&l.b<=a[head].b) tail--;
a[++tail]=l;
}
line getans(ll x)
{
int l=head,r=tail;
while (l+1<r)
{
int mid=l+r>>1;
if (a[mid-1].f(x)>a[mid].f(x)) l=mid+1;
else r=mid-1;
}
line u=a[tail];
for (int i=max(l-2,head);i<=min(l+2,tail);i++)
//for (int i=head;i<=tail;i++)
if (a[i].f(x)<=u.f(x)) u=a[i];
return u;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("e.in","r",stdin);
freopen("e.out","w",stdout);
#endif
n=read(),m=read();first=1,last=n;
head=tail=300005;
ll qwq=1;
while (m--)
{
int op=read();
if (op==1)
{
int k=read();n+=k;first-=k;qwq=1;
ll b=-deltas*(first-1)-deltab;
ins_tail(first-1,b);
printf("1 0\n");
}
if (op==2)
{
int k=read();
ll b=-deltas*last-deltab;
ins_head(last,b);
if (!qwq) qwq=n+1;
printf("%I64d %d\n",qwq,0);
n+=k;last+=k;
}
if (op==3)
{
int b=read(),s=read();qwq=0;
deltab+=b+1ll*(1-first)*s,deltas+=s;
line ans=getans(deltas);
printf("%I64d %I64d\n",ans.k+2-first,ans.f(deltas)+deltab);
}
//for (int i=head;i<=tail;i++) cout<<a[i].k<<' '<<a[i].b<<endl;cout<<endl;
}
return 0;
//NOTICE LONG LONG!!!!!
}

  F先咕着。

  感觉非常可怕的是看完sol不是感叹题好神而是感叹自己傻逼。

  靠着偶尔快起来的切傻逼题的手速上了红,事实上还是打铁实力。简直自闭。

  小号打的。result:rank 254 rating -19

Codeforces Round #545 Div. 1自闭记的更多相关文章

  1. Educational Codeforces Round 58 Div. 2 自闭记

    明明多个几秒就能场上AK了.自闭. A:签到. #include<iostream> #include<cstdio> #include<cmath> #inclu ...

  2. Codeforces Round #554 (Div. 2)自闭记

    A 签到 #include<bits/stdc++.h> using namespace std; ],t[],ans; int main() { scanf("%d%d&quo ...

  3. Codeforces Round #528 Div. 1 自闭记

    整天自闭. A:有各种讨论方式.我按横坐标排了下然后讨论了下纵坐标单调和不单调两种情况.写了15min也就算了,谁能告诉我printf和cout输出不一样是咋回事啊?又调了10min啊?upd:突然想 ...

  4. Codeforces Round #526 Div. 1 自闭记

    日常猝死. A:f[i]表示子树内包含根且可以继续向上延伸的路径的最大价值,统计答案考虑合并两条路径即可. #include<iostream> #include<cstdio> ...

  5. Codeforces Round #567 (Div. 2)自闭记

    嘿嘿嘿,第一篇文章,感觉代码可以缩起来简直不要太爽 打个div2发挥都这么差... 平均一题fail一次,还调不出错,自闭了 又一次跳A开B,又一次B傻逼错误调不出来 罚时上天,E还傻逼了..本来这场 ...

  6. Codeforces Round #530 Div. 1 自闭记

    A:显然应该让未确定的大小尽量大.不知道写了啥就wa了一发. #include<iostream> #include<cstdio> #include<cmath> ...

  7. Codeforces Round #525 Div. 2 自闭记

    A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...

  8. Codeforces Round #545 (Div. 1) 简要题解

    这里没有翻译 Codeforces Round #545 (Div. 1) T1 对于每行每列分别离散化,求出大于这个位置的数字的个数即可. # include <bits/stdc++.h&g ...

  9. Codeforces Round #545 (Div. 1) Solution

    人生第一场Div. 1 结果因为想D想太久不晓得Floyd判环法.C不会拆点.E想了个奇奇怪怪的set+堆+一堆乱七八糟的标记的贼难写的做法滚粗了qwq靠手速上分qwqqq A. Skyscraper ...

随机推荐

  1. mybatis抽取出的工具-(一)通用标记解析器(即拿即用)

    目录 1. 简介 1.1 mybatis-config.xml 中使用 1.2 xxxMapper.xml 中使用 2. 原理 2.1 GenericTokenParser 成员变量 2.2 Gene ...

  2. 一起学习造轮子(三):从零开始写一个React-Redux

    本文是一起学习造轮子系列的第三篇,本篇我们将从零开始写一个React-Redux,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Promises/A+,Re ...

  3. pycharm 常用快捷键操作

    #最重要的快捷键 1. ctrl+shift+A:万能命令行 2. shift两次:查看资源文件 #新建工程第一步操作 1. module设置把空包分层去掉,compact empty middle ...

  4. xadmin的使用

    01-下载源码 GitHub地址:https://github.com/sshwsfc/xadmin # 安装xadmin 由于使用的是Django2.0的版本,所以需要安装xadmin项目djang ...

  5. Python全栈开发之路 【第十八篇】:Ajax技术

    Ajax技术 Ajax = 异步 JavaScript 和 XML. Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 1.jQuery的load()方法 jQuery loa ...

  6. SQL SERVER按多字段查找重复的数据并删除只保留一条

    由于一次操作失误,给表中插入了多条重复的数据,所以就需要删除重复的数据只保留一条,一时想不到好方法,各种查资料,终于找到了,特意写到这里,方便以后自己用~ 查询: select A.n_PatentI ...

  7. Linux模拟控制网络时延

    之前以为可以使用Linux自带的工具模拟控制网络时延,所以上网找了一些资料.后来发现,找到的资料目前只支持在一个网卡上模拟发送报文的时延,而不能设置有差别的网络时延,或者说当要模拟的向A发送的时延与要 ...

  8. Python之json使用

    一.概念 json是一种通用的数据类型,任何语言都认识 接口返回的数据类型都是json 长得像字典,形式也是k-v { } 其实json是字符串 字符串不能用key.value来取值,要先转成字典才可 ...

  9. 【学习总结】Git学习-参考廖雪峰老师教程五-远程仓库

    学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...

  10. hadoop实例-网站用户行为分析

    一.数据集 网站用户购物行为数据集2030万条,包括raw_user.csv(2000万条)和small_user.csv(30万条,适合新手) 字段说明: user_id 用户编号,item_id ...