您的位置:首页 > 其它

Educational Codeforces Round 23 A-F

2017-06-16 11:32 579 查看
感觉这种比赛就是拼手速啊QwQ

A.Treasure Hunt

题目大意:平面直角坐标系中给定起点和终点,每次可以从(a,b)走向(a+x,b+y),(a-x,b-y),(a+x,b-y),(a-x,b+y)这四个点。

问从起点能否到达终点。

要求O(1)做法。

题解:这个第一遍提交还WA了QwQ。

首先如果这个是在一维直线上的,那么只要判断|x1-x2|是不是x的倍数即可。

在二维的情况中,不仅要判断两个是否同时满足,还要保证|x1-x2|/x和|y1-y2|/y是不是同奇偶。

B.Makes And The Product

题目大意:给定一列数,找到三个下标不同的数,使得她们的乘积最小,问有多少种方案。

要求O(n)做法。

题解:排序后分类讨论即可。讨论结果和代码差不多。

C.Really Big Numbers

题目大意:给定n和s,问在不大于n的正整数中,满足这个数减去各位数字之和不小于s的数字有多少。

n,s<=1e18

题解:假设这个数是x,各位数字之和为d,那么x最多是18位数,每位最大是9,所以d<=18*9=162。

也就是对于>=s+162的数字x是一定满足条件的。

又要求x-d>=s所以x>=s+d>=s所以小于s的所有数字是不满足条件的。

因此判断一下中间那些数即可。

D. Imbalanced Array

题目大意:给定一列数,每个区间的值为这个区间的最大值减去最小值。求所有区间的值的和。

要求O(n)做法。

题解:首先那个差是无关紧要的。

问题变为求所有区间的最大/小值的和。

那这个东西显然是可以用单调栈来维护的。

E.Choosing The Commander

题目大意:维护一个数据结构,实现三种操作:

1.加入一个数x。

2.把x删除。

3.给定两个数a,b,问已经加入并且没有被删除的x中有多少个x满足x^a小于b。(^是异或)

q<=1e5,a,b,x<=1e8。

题解:一看到异或果断想trie。然后前两个操作就变成了修改链值,暴力即可。

第三个操作,分a的第d位是0还是1讨论,并保存一个延trie上当前路径走下来到这个节点的值是多少(记作v)。

举例来讲,如果a的第d位是0,那么第d-1位走0是一定可行的。这个时候如果b的第d-1位是1,那么说明只要第d-1位为0那么接下来再怎么走都可以,直接返回下一个结点的权值即可。(因为是从高位向低位考虑的)

同时如果第d-1位选择走1,那就要保证b的第d-1位是1(或者也可以认为把v的第d-1位置为1后小于b)。

a的第d位是1同理,详见代码。

复杂度未知。(可能是玄学)

F. MEX Queries

题目大意:维护数据结构,实现4种操作:

1.将区间[L,R]全部赋为1.

2.将区间[L,R]全部赋为0.

3.将区间[L,R]全部取反.

4.询问当前区间的mex。mex即当前序列1,2,....,中第一个为0的数。

初始全部为0。

L<=R<=1e18

要求O(mlgm)的做法。

题解:首先L,R这么大没有意义离散化即可。

这样就用线段树暴力维护即可。

注意有两个标记(取反和赋值)注意考虑维护的先后顺序。

两个坑点一个是你不能只把L,R离散化,还要将L+1和R+1离散化。

这样可以避免形如1 1 2; 1 4 5; 4 ;这样的操作序列输出错误的答案4。

另一个是就算数据没有1也要把1离散化了。

这样避免所有L都>1时会输出奇怪的数字。

还有就是不要忘了用long long读入。

代码们:

A.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
int x1,y1,x2,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int x,y;scanf("%d%d",&x,&y);
int px=abs(x1-x2),py=abs(y1-y2);
if(px%x==0&&py%y==0&&abs(px/x-py/y)%2==0) printf("YES\n");
else printf("NO\n");return 0;
}

B.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
#define lint long long
using namespace std;
int a[MAXN];
int main()
{
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
if(a[1]==a[3])
{
int cnt=0;
for(int i=1;i<=n;i++)
if(a[i]==a[1]) cnt++;
printf("%I64d\n",(lint)cnt*(cnt-1)/2*(cnt-2)/3);
return 0;
}
if(a[1]<a[2])
{
int cnt2=0,cnt3=0;
for(int i=1;i<=n;i++)
{
if(a[i]==a[2]) cnt2++;
if(a[i]==a[3]) cnt3++;
}
if(a[2]==a[3]) printf("%I64d\n",(lint)cnt2*(cnt2-1)/2);
else printf("%d\n",cnt3);
return 0;
}
if(a[1]==a[2])
{
int cnt=0;
for(int i=1;i<=n;i++)
if(a[i]==a[3]) cnt++;
printf("%d\n",cnt);
return 0;
}
return 0;
}C.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lint long long
using namespace std;
int a[100];
int main()
{
lint n,s;scanf("%I64d%I64d",&n,&s);
lint ans=max(n-s-161,0LL);
for(lint i=min(s+161,n);i>=s;i--)
{
lint x=i;int len=0;
while(x)
{
a[++len]=x%10;
x/=10;
}
int ss=0;
for(int j=1;j<=len;j++)
ss+=a[j];
if(i-ss>=s) ans++;
}
printf("%I64d\n",ans);
return 0;
}

D.#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#define MAXN 1000010
#define lint long long
#define INF INT_MAX
using namespace std;
stack<int> s1,s2;
lint ans1,ans2,ans;
int a[MAXN];
int main()
{
int n;scanf("%d",&n);
while(!s1.empty()) s1.pop();s1.push(0);
while(!s2.empty()) s2.pop();s2.push(0);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);a[0]=0;
while(s1.top()&&a[i]<a[s1.top()])
{
int t=s1.top();s1.pop();
ans1-=(lint)a[t]*(t-s1.top());
}
ans1+=(lint)a[i]*(i-s1.top());s1.push(i);
a[0]=INF;
while(s2.top()&&a[i]>a[s2.top()])
{
int t=s2.top();s2.pop();
ans2-=(lint)a[t]*(t-s2.top());
}
ans2+=(lint)a[i]*(i-s2.top());s2.push(i);
ans+=ans2-ans1;
}
printf("%I64d\n",ans);
return 0;
}E.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<assert.h>
using namespace std;
struct trie{
int s;
trie *ch[2];
}*rt;
int maintain(trie* &rt)
{
rt->s=0;
if(rt->ch[0]!=NULL) rt->s+=rt->ch[0]->s;
if(rt->ch[1]!=NULL) rt->s+=rt->ch[1]->s;
return 0;
}
int update(trie* &rt,int p,int v,int d)
{
if(rt==NULL)
{
rt=new trie;rt->s=0;
rt->ch[0]=rt->ch[1]=NULL;
}
if(!d) return rt->s+=v;
else d--;
int g=(p&(1<<d))>>d;
update(rt->ch[g],p,v,d);
maintain(rt);return 0;
}
int query(trie* &rt,int p,int l,int d,int v)
{
if(!d) return rt->s;
else d--;
int g=(p&(1<<d))>>d,ans=0;
if(g==0)
{
if(rt->ch[0]!=NULL)
{
if((l&(1<<d))>>d) ans+=rt->ch[0]->s;
else ans+=query(rt->ch[0],p,l,d,v);
}
if(rt->ch[1]!=NULL&&(v|(1<<d))<l)
ans+=query(rt->ch[1],p,l,d,v|(1<<d));
}
else{
if(rt->ch[0]!=NULL&&(v|(1<<d))<l)
ans+=query(rt->ch[0],p,l,d,v|(1<<d));
if(rt->ch[1]!=NULL)
{
if((l&(1<<d))>>d) ans+=rt->ch[1]->s;
else ans+=query(rt->ch[1],p,l,d,v);
}
}
return ans;
}
int main()
{
rt=new trie;rt->s=0;
rt->ch[0]=rt->ch[1]=NULL;
int q;scanf("%d",&q);
while(q--)
{
int opt;scanf("%d",&opt);
if(opt==1||opt==2)
{
int p;scanf("%d",&p);
if(opt==1) update(rt,p,1,28);
else update(rt,p,-1,28);
}
else{
int p,l;scanf("%d%d",&p,&l);
printf("%d\n",query(rt,p,l,28,0));
}
}
return 0;
}

F.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define MAXQ 100010
#define lint long long
using namespace std;
struct segment{
int s,l,r,t;
bool revt,updt;
segment *ch[2];
}*rt;
vector<lint> v;
lint L[MAXQ],R[MAXQ];
int OPT[MAXQ];
inline int push_up(segment* &rt)
{
rt->s=rt->ch[0]->s+rt->ch[1]->s;
return 0;
}
int build(segment* &rt,int l,int r)
{
rt=new segment;
rt->ch[0]=rt->ch[1]=NULL;
rt->l=l;rt->r=r;
rt->revt=false;
rt->updt=rt->s=0;
if(l==r) return 0;
int mid=(l+r)>>1;
build(rt->ch[0],l,mid);
build(rt->ch[1],mid+1,r);
return 0;
}
int update_tags(segment* &rt,int t)
{
rt->t=t;
rt->updt=true;
rt->revt=false;
rt->s=(rt->r-rt->l+1)*t;
return 0;
}
int update_rev(segment* &rt)
{
if(rt->updt)
{
rt->t=1-rt->t;
rt->s=(rt->r-rt->l+1)*rt->t;
rt->revt=false;
}
else{
rt->revt=!rt->revt;
rt->s=rt->r-rt->l+1-rt->s;
}
return 0;
}
int push_down(segment* &rt)
{
if(rt->updt)
{
update_tags(rt->ch[0],rt->t);
update_tags(rt->ch[1],rt->t);
}
if(rt->revt)
{
update_rev(rt->ch[0]);
update_rev(rt->ch[1]);
}
rt->revt=false;
rt->updt=false;
rt->t=0;return 0;
}
int update(segment* &rt,int s,int t,int v)
{
int l=rt->l,r=rt->r;
if(s<=l&&r<=t)
{
rt->revt=false;
rt->updt=true;
rt->t=v;
rt->s=(r-l+1)*v;
return 0;
}
int mid=(l+r)>>1;
if(rt->revt||rt->updt) push_down(rt);
if(s<=mid) update(rt->ch[0],s,t,v);
if(mid<t) update(rt->ch[1],s,t,v);
push_up(rt);return 0;
}
int query(segm
e93e
ent* &rt)
{
int s=rt->s,l=rt->l,r=rt->r;
if(l==r) return s?(l+1):r;
int mid=(l+r)>>1;
if(rt->updt||rt->revt) push_down(rt);
if(rt->ch[0]->s==rt->ch[0]->r-rt->ch[0]->l+1) return query(rt->ch[1]);
else return query(rt->ch[0]);
}
int reverse(segment* &rt,int s,int t)
{
int l=rt->l,r=rt->r;
if(s<=l&&r<=t) return update_rev(rt);
int mid=(l+r)>>1;
if(rt->updt||rt->revt) push_down(rt);
if(s<=mid) reverse(rt->ch[0],s,t);
if(mid<t) reverse(rt->ch[1],s,t);
push_up(rt);return 0;
}
int getid(lint x)
{
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
int main()
{
int q;scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%I64d%I64d",&OPT[i],&L[i],&R[i]);
v.push_back(L[i]);v.push_back(L[i]+1);
v.push_back(R[i]);v.push_back(R[i]+1);
}
v.push_back(1);
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
build(rt,1,v.size());
for(int i=1;i<=q;i++)
{
int l=getid(L[i]),r=getid(R[i]),opt=OPT[i];
if(opt==1||opt==2) update(rt,l,r,opt&1);
else reverse(rt,l,r);
printf("%I64d\n",v[query(rt)-1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: