Codeforces Round #567 Div. 2
A:签到。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
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;
}
ll x,y,z;
signed main()
{
cin>>x>>y>>z;
cout<<(x+y)/z<<' ';
if (x%z+y%z<z) cout<<0;
else cout<<min(z-x%z,z-y%z);
return 0;
//NOTICE LONG LONG!!!!!
}
B:显然在中间截比较优。于是就找到在左侧和在右侧的最靠近中点的切割点。注意不能有前导0。高精加即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#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,a[N],b[N],c[N],d[N],len1=N,len2=N;
char s[N];
signed main()
{
n=read();
scanf("%s",s+1);
int x=0,y=n+1;
for (int i=1;i<n;i++)
if (s[i+1]!='0')
{
if (i<=n/2) x=max(x,i);
else y=min(y,i);
}
if (x>0)
{
int lena=0,lenb=0;
for (int i=x;i>=1;i--) a[++lena]=s[i]-'0';
for (int i=n;i>x;i--) b[++lenb]=s[i]-'0';
for (int i=1;i<=max(lena,lenb);i++)
{
a[i]+=b[i];
a[i+1]+=a[i]/10;
a[i]%=10;
}
len1=max(lena,lenb);
if (a[len1+1]) len1++;
}
if (y<=n)
{
int lena=0,lenb=0;
for (int i=y;i>=1;i--) c[++lena]=s[i]-'0';
for (int i=n;i>y;i--) d[++lenb]=s[i]-'0';
for (int i=1;i<=max(lena,lenb);i++)
{
c[i]+=d[i];
c[i+1]+=c[i]/10;
c[i]%=10;
}
len2=max(lena,lenb);
if (c[len2+1]) len2++;
}
if (len1<len2)
{
for (int i=len1;i>=1;i--) printf("%d",a[i]);
}
else
if (len1>len2)
{
for (int i=len2;i>=1;i--) printf("%d",c[i]);
}
else
{
bool flag1=0;
for (int i=len1;i>=1;i--)
if (a[i]!=c[i])
{
flag1=a[i]<c[i];
break;
}
if (flag1) for (int i=len1;i>=1;i--) printf("%d",a[i]);
else for (int i=len2;i>=1;i--) printf("%d",c[i]);
}
return 0;
//NOTICE LONG LONG!!!!!
}
C:每个点处理出该列中以该位置为起点形成的三段是什么样子的。注意第三段长度对第二段取min。然后枚举每一行,找到三段相同且合法的子段计算贡献即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 1010
#define mp(x,y) make_pair((x),(y))
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<char,int> pii;
int n,m;
pii f[N][N][3];
char a[N][N];
ll ans;
bool issame(int i,int x,int y)
{
for (int j=0;j<3;j++)
if (f[i][x][j]!=f[i][y][j]) return 0;
return 1;
}
signed main()
{
n=read(),m=read();
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
a[i][j]=getc();
for (int i=1;i<=m;i++) f[n][i][0]=mp(a[n][i],1);
for (int i=n-1;i>=1;i--)
for (int j=1;j<=m;j++)
if (a[i][j]==a[i+1][j])
{
for (int k=0;k<3;k++) f[i][j][k]=f[i+1][j][k];
f[i][j][0].second++;
}
else
{
for (int k=1;k<3;k++) f[i][j][k]=f[i+1][j][k-1];
f[i][j][0]=mp(a[i][j],1);
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
f[i][j][2].second=min(f[i][j][2].second,f[i][j][1].second);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
int t=j;
while (t<m&&issame(i,j,t+1)) t++;
if (f[i][j][0].second==f[i][j][1].second&&f[i][j][1].second==f[i][j][2].second) ans+=(t-j+1)*(t-j+2)/2;
j=t;
}
}
cout<<ans;
return 0;
//NOTICE LONG LONG!!!!!
}
D:可以首先对每个询问二分出该次要加的数的值是多少。然后问题变为多次询问序列中第k个<=p的数是多少。可以将数从小到大考虑,treap维护查询第k大。事实上直接离线即可,开始的二分有点多余。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 500010
#define int long long
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
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,q,a[N],b[N],s[N],cnt[N],root,Cnt;
struct data
{
int k,p,i,ans;
bool operator <(const data&a) const
{
return i<a.i;
}
}Q[N];
bool cmp(const data&a,const data&b)
{
return a.p<b.p;
}
vector<int> pos[N];
struct data2{int ch[2],s,p,x;
}tree[N];
void up(int k){tree[k].s=tree[lson].s+tree[rson].s+1;}
void move(int &k,int p)
{
int t=tree[k].ch[p];
tree[k].ch[p]=tree[t].ch[!p],tree[t].ch[!p]=k,up(k),up(t),k=t;
}
void ins(int &k,int x)
{
if (k==0) {k=++Cnt;tree[k].x=x,tree[k].p=rand(),tree[k].s=1;return;}
tree[k].s++;
if (tree[k].x<x) {ins(rson,x);if (tree[rson].p>tree[k].p) move(k,1);}
else {ins(lson,x);if (tree[lson].p>tree[k].p) move(k,0);}
}
int query(int k,int x)
{
if (tree[lson].s+1==x) return tree[k].x;
if (tree[lson].s+1>x) return query(lson,x);
else return query(rson,x-tree[lson].s-1);
}
signed main()
{
srand(time(0));
m=read(),n=read(),q=read();
for (int i=1;i<=m;i++) a[read()]++;
for (int i=1;i<=n;i++) pos[a[i]].push_back(i);
for (int i=1;i<=n;i++) b[a[i]]++;cnt[0]=b[0];
for (int i=1;i<=m;i++) s[i]=s[i-1]+i*b[i],cnt[i]=cnt[i-1]+b[i];
for (int i=1;i<=q;i++)
{
Q[i].i=i;
int x=read()-m;
if (x+m>m*n) Q[i].k=(x+m-1)%n+1,Q[i].p=m;
else
{
int l=0,r=m,p=0;
while (l<=r)
{
int mid=l+r>>1;
if (cnt[mid]*mid-s[mid]<x) p=mid,l=mid+1;
else r=mid-1;
}
int k=x-(cnt[p]*p-s[p]);
Q[i].k=k,Q[i].p=p;
}
}
sort(Q+1,Q+q+1,cmp);
int cur=0;
for (int i=0;i<=m;i++)
{
for (int j:pos[i]) ins(root,j);
while (cur<q&&Q[cur+1].p==i)
{
cur++;
Q[cur].ans=query(root,Q[cur].k);
}
}
sort(Q+1,Q+q+1);
for (int i=1;i<=q;i++) printf("%d\n",Q[i].ans);
return 0;
//NOTICE LONG LONG!!!!!
}
E:E1就是个思博暴力,显然能切就切不会改变可行性。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#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,b[N<<2],t;
int cnt[N<<2];
struct data{int x1,y1,x2,y2;
}a[N],c[N];
bool solve(int l,int r)
{
if (l==r) return 1;
for (int i=1;i<=t;i++) cnt[i]=0;
for (int i=l;i<=r;i++) cnt[a[i].x1+1]++,cnt[a[i].x2]--;
int mx=0,mn=t+1;
for (int i=l;i<=r;i++) mx=max(mx,a[i].x1),mn=min(mn,a[i].x2);
int s=0,p=-1;
for (int i=1;i<=t;i++)
{
s+=cnt[i];
if (i>=mn&&i<=mx&&s==0) {p=i;break;}
}
if (p!=-1)
{
int u=l-1;
for (int i=l;i<=r;i++)
if (a[i].x2<=p) c[++u]=a[i];
int mid=u;
for (int i=l;i<=r;i++)
if (a[i].x1>=p) c[++u]=a[i];
for (int i=l;i<=r;i++) a[i]=c[i];
return solve(l,mid)&&solve(mid+1,r);
}
for (int i=1;i<=t;i++) cnt[i]=0;
for (int i=l;i<=r;i++) cnt[a[i].y1+1]++,cnt[a[i].y2]--;
mx=0,mn=t+1;
for (int i=l;i<=r;i++) mx=max(mx,a[i].y1),mn=min(mn,a[i].y2);
s=0,p=-1;
for (int i=1;i<=t;i++)
{
s+=cnt[i];
if (i>=mn&&i<=mx&&s==0) {p=i;break;}
}
if (p!=-1)
{
int u=l-1;
for (int i=l;i<=r;i++)
if (a[i].y2<=p) c[++u]=a[i];
int mid=u;
for (int i=l;i<=r;i++)
if (a[i].y1>=p) c[++u]=a[i];
for (int i=l;i<=r;i++) a[i]=c[i];
return solve(l,mid)&&solve(mid+1,r);
}
return 0;
}
signed main()
{
n=read();
for (int i=1;i<=n;i++)
{
b[++t]=a[i].x1=read();
b[++t]=a[i].y1=read();
b[++t]=a[i].x2=read();
b[++t]=a[i].y2=read();
}
sort(b+1,b+t+1);
t=unique(b+1,b+t+1)-b-1;
for (int i=1;i<=n;i++)
{
a[i].x1=lower_bound(b+1,b+t+1,a[i].x1)-b;
a[i].y1=lower_bound(b+1,b+t+1,a[i].y1)-b;
a[i].x2=lower_bound(b+1,b+t+1,a[i].x2)-b;
a[i].y2=lower_bound(b+1,b+t+1,a[i].y2)-b;
}
if (solve(1,n)) cout<<"YES";else cout<<"NO";
return 0;
//NOTICE LONG LONG!!!!!
}
E2的话,基本思路肯定没法有什么变化,如果要保证复杂度,容易想到每次切割都只能花费相当于较少部分矩形个数的代价。那么首先切割时不能把两部分分别递归下去,而是要递归较少的部分并把其从整体中删掉,可以链表实现。然后考虑怎样以这样的复杂度找到一种切割方案。将矩形集合复制成四份,并分别按x1,x2,y1,y2排序,同时处理四份矩形集合,找到一种切割时就立即停止,这样就能保证扫过的部分矩形数量不大于一半了。判断能否切割只需要记录另一维坐标的极值,比如对于x1从小到大排序后,记录x2的最大值即可。实现时像我一样蠢的话就会出现大量的同一份代码写四次。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 1000000010
#define N 100010
#define del(x) {nxt1[pre1[pos1[x]]]=nxt1[pos1[x]];pre1[nxt1[pos1[x]]]=pre1[pos1[x]];nxt2[pre2[pos2[x]]]=nxt2[pos2[x]];pre2[nxt2[pos2[x]]]=pre2[pos2[x]];nxt3[pre3[pos3[x]]]=nxt3[pos3[x]];pre3[nxt3[pos3[x]]]=pre3[pos3[x]];nxt4[pre4[pos4[x]]]=nxt4[pos4[x]];pre4[nxt4[pos4[x]]]=pre4[pos4[x]];}
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;
struct data{int x1,y1,x2,y2,i;
}a[N];
bool cmp1(const data&a,const data&b)
{
return a.x1<b.x1;
}
bool cmp2(const data&a,const data&b)
{
return a.x2>b.x2;
}
bool cmp3(const data&a,const data&b)
{
return a.y1<b.y1;
}
bool cmp4(const data&a,const data&b)
{
return a.y2>b.y2;
}
bool solve(data *a,int n)
{
data a1[n+1],a2[n+1],a3[n+1],a4[n+1];
int nxt1[n+2],nxt2[n+2],nxt3[n+2],nxt4[n+2];
int pre1[n+2],pre2[n+2],pre3[n+2],pre4[n+2];
for (int i=0;i<=n;i++)
{
a[i].i=i;
a1[i]=a2[i]=a3[i]=a4[i]=a[i];
nxt1[i]=nxt2[i]=nxt3[i]=nxt4[i]=i+1;
pre1[i+1]=pre2[i+1]=pre3[i+1]=pre4[i+1]=i;
}
sort(a1+1,a1+n+1,cmp1);sort(a2+1,a2+n+1,cmp2);sort(a3+1,a3+n+1,cmp3);sort(a4+1,a4+n+1,cmp4);
int pos1[n+2],pos2[n+2],pos3[n+2],pos4[n+2];
for (int i=1;i<=n;i++) pos1[a1[i].i]=i,pos2[a2[i].i]=i,pos3[a3[i].i]=i,pos4[a4[i].i]=i;
while (n>1)
{
int tmp=0;
int mxx2=-inf,mnx1=inf,mxy2=-inf,mny1=inf;
int cur1=0,cur2=0,cur3=0,cur4=0;
bool flag=0;
for (int i=1;i<=n/2;i++)
{
cur1=nxt1[cur1];
cur2=nxt2[cur2];
cur3=nxt3[cur3];
cur4=nxt4[cur4];
mxx2=max(mxx2,a1[cur1].x2);
mnx1=min(mnx1,a2[cur2].x1);
mxy2=max(mxy2,a3[cur3].y2);
mny1=min(mny1,a4[cur4].y1);
if (mxx2<=a1[nxt1[cur1]].x1)
{
flag=1;
data b[i+1];
for (int j=1;j<=i;j++)
{
b[j]=a1[cur1];
int x=a1[cur1].i;
cur1=pre1[cur1];
del(x);
}
if (!solve(b,i)) return 0;
else {n-=i;break;}
}
if (mnx1>=a2[nxt2[cur2]].x2)
{
flag=1;
data b[i+1];
for (int j=1;j<=i;j++)
{
b[j]=a2[cur2];
int x=a2[cur2].i;
cur2=pre2[cur2];
del(x);
}
if (!solve(b,i)) return 0;
else {n-=i;break;}
}
if (mxy2<=a3[nxt3[cur3]].y1)
{
flag=1;
data b[i+1];
for (int j=1;j<=i;j++)
{
b[j]=a3[cur3];
int x=a3[cur3].i;
cur3=pre3[cur3];
del(x);
}
if (!solve(b,i)) return 0;
else {n-=i;break;}
}
if (mny1>=a4[nxt4[cur4]].y2)
{
flag=1;
data b[i+1];
for (int j=1;j<=i;j++)
{
b[j]=a4[cur4];
int x=a4[cur4].i;
cur4=pre4[cur4];
del(x);
}
if (!solve(b,i)) return 0;
else {n-=i;break;}
}
}
if (!flag) return 0;
}
return 1;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
n=read();
for (int i=1;i<=n;i++) a[i].x1=read(),a[i].y1=read(),a[i].x2=read(),a[i].y2=read();
if (solve(a,n)) cout<<"YES";else cout<<"NO";
return 0;
//NOTICE LONG LONG!!!!!
}
小小小小号。result:rank 3 rating +218
Codeforces Round #567 Div. 2的更多相关文章
- Codeforces Round #567 (Div. 2)A
A. Chunga-Changa 题目链接:http://codeforces.com/contest/1181/problem/A 题目 Soon after the Chunga-Changa i ...
- Codeforces Round #567 (Div. 2) E2 A Story of One Country (Hard)
https://codeforces.com/contest/1181/problem/E2 想到了划分的方法跟题解一样,但是没理清楚复杂度,很难受. 看了题解觉得很有道理,还是自己太菜了. 然后直接 ...
- Codeforces Round #567 (Div. 2)B. Split a Number (字符串,贪心)
B. Split a Number time limit per test2 seconds memory limit per test512 megabytes inputstandard inpu ...
- Codeforces Round #567 (Div. 2)自闭记
嘿嘿嘿,第一篇文章,感觉代码可以缩起来简直不要太爽 打个div2发挥都这么差... 平均一题fail一次,还调不出错,自闭了 又一次跳A开B,又一次B傻逼错误调不出来 罚时上天,E还傻逼了..本来这场 ...
- Codeforces Round #567 (Div. 2) A.Chunga-Changa
原文链接:传送 #include"algorithm" #include"iostream" #include"cmath" using n ...
- Codeforces Round #567 (Div. 2) B. Split a Number
Split a Number time limit per test 2 seconds memory limit per test 512 megabytes input standard inpu ...
- 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 ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
随机推荐
- 【软工实践】Alpha冲刺(6/6)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 tomcat的学习与实现 服务器后端部署,API接口的beta版实现 后端代码 ...
- ipv4的TCP的几个状态 (SYN, FIN, ACK, PSH, RST, URG)
1 在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG. 2 3 其中,对于我们日常的分析有用的就是前面的五个字段. 4 5 它们的含义是 ...
- POST请求BODY格式区别
在PostMan中用Post方式,Body有form-data,x-www-form-urlencoded,raw,binary四种. Request Header示例:POST /upload.do ...
- Python开发人员指南
本指南是一个全面的资源贡献 给Python的 -为新的和经验丰富的贡献者.这是 保持由维护的Python同一社区.我们欢迎您对Python的贡献! 快速参考 这是设置和添加补丁所需的基本步骤.了解基础 ...
- MySQL8新特性(2)--mysql的升级过程
在之前的版本中,安装新的版本mysql之后,mysql server在下一次启动时,会自动升级数据字典表,然后dba需要执行mysql_upgrade手动升级mysql schema中的系统表,以及其 ...
- String.format()详细用法
String.format()字符串常规类型格式化的两种重载方式 format(String format, Object… args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字 ...
- Win10 cmd控制台程序会被鼠标单击暂停的解决办法
右键单击顶部白框,选择属性或默认值,将快速编辑模式的勾取消就可以了,最后记得点击确定
- openresty开发系列32--openresty执行流程之1初始化阶段
openresty开发系列32--openresty执行流程之初始化阶段 一)初始化阶段 1)init_by_lua init_by_lua_block init_by_lua_file语 ...
- python2中的unicode()函数在python3中会报错:
python2中的unicode()函数在python3中会报错:NameError: name 'unicode' is not defined There is no such name in P ...
- LeetCode_437. Path Sum III
437. Path Sum III Easy You are given a binary tree in which each node contains an integer value. Fin ...